arraysxpathmarklogictde

MarkLogic TDE Xpath values from JSON string array


I want to build a a tde with a row with an id and each value of an array in the original document.

I get a row for each element but the values are null and ignored.

Seems if the context is set to anything not an array the ../uri works but never when the context is an array.

I am struggling to find good resources for MarkLogic TDE other than simplistic examples,

Example document (snippet)

 "instance": {
        "uri": "/A/Uri/of/some/type.json", 
         "types": [
          "a", 
          "b", 
          "c"
      ]
}

Template

{
  "template":{
    "context":"/instance/types",
    "collections":["Collection"],
    "enabled" : true,
    "rows":[
      {
        "schemaName":"namespace",
        "viewName":"uri2types",
        "columns":[
          {
            "name":"uri",
            "scalarType":"anyURI",
            "val":"../uri",
            "nullable":true,
            "invalidValues": "ignore"
          }
          ,
          {
            "name":"type",
            "scalarType":"string",
            "val":"/node()",
            "nullable":true,
            "invalidValues": "ignore"
          }
        ]
      }
    ]
  }
}

Result

     {
        "/A/Uri/of/some/type.json": [
            {
                "row": {
                    "schema": "namespace", 
                    "view": "uri2types", 
                    "data": {
                        "rownum": "1"
                }
            }
        }, 
            {
                "row": {
                    "schema": "namespace", 
                    "view": "uri2types", 
                    "data": {
                        "rownum": "2"
                }
            }
        }, 
            {
                "row": {
                "schema": "namespace", 
                "view": "uri2types", 
                "data": {
                    "rownum": "3"
                }
                }
            }
        ]
        }

**Result Wanted** 


    {
        "/A/Uri/of/some/type.json": [
        {
            "row": {
                    "schema": "namespace", 
                    "view": "uri2types", 
                    "data": {
                        "rownum": "1",
                        "uri":"/A/Uri/of/some/type.json":,
                        "type"="a"

                    }
                }
            }, 
        {
            "row": {
                "schema": "namespace", 
                "view": "uri2types", 
                "data": {
                    "rownum": "2",
                    "uri":"/A/Uri/of/some/type.json":,
                    "type":"b"
                }
            }
        }, 
        {
            "row": {
                "schema": "namespace", 
                "view": "uri2types", 
                "data": {
                    "rownum": "3",
                    "uri":"/A/Uri/of/some/type.json":,
                    "type":"c"
                }
            }
        }
    ]
    }

Solution

  • The expression /node() for the type column will attempt to get child nodes of the text node containing your type, but a text node doesn't have any child nodes. data() or . is more appropriate.

    The expression ../uri for the uri column does not go up the tree high enough. The full MarkLogic XPath to get to your type values would be /object-node()/object-node('instance')/array-node('types')/text(). You need to go up two levels to escape from the surrounding array-node. It can help to rewrite /instance/types to /instance/array-node()/types:

    'use strict';
    
    let json = xdmp.toJSON({
      "instance": {
        "uri": "/A/Uri/of/some/type.json", 
        "types": [
          "a", 
          "b", 
          "c"
        ]
      }
    });
    let tpl = xdmp.toJSON({
      "template":{
        "context":"/instance/array-node()/types",
        "enabled" : true,
        "rows":[
          {
            "schemaName":"namespace",
            "viewName":"uri2types",
            "columns":[
              {
                "name":"uri",
                "scalarType":"anyURI",
                "val":"../../uri",
                "nullable":true,
                "invalidValues": "ignore"
              }
              ,
              {
                "name":"type",
                "scalarType":"string",
                "val":"data()",
                "nullable":true,
                "invalidValues": "ignore"
              }
            ]
          }
        ]
      }
    });
    tde.validate([tpl]);
    tde.nodeDataExtract([json], [tpl]);
    

    HTH!