Search code examples
xquerymarklogic

XQuery to get a multi-valued field in MarkLogic


I am getting this error since we made a field multi-valued (a list of multiple of the same elements):

argX is not of type xs:anyAtomicType?

This is the query that we are using to get values from MarkLogic:

declare variable $uris as xs:string  external;
for $uri in tokenize($uris,';')
    let $doc := fn:doc($uri)
    return xdmp:gzip(
        xdmp:unquote(fn:concat(
            "<item>",
            "<uri>",
            $uri,
            "</uri>",
            "<date-loaded>",
            $doc/date-loaded,
            "</date-loaded>",
            "<collections>",
                string-join(xdmp:document-get-collections($uri), ";"),
            "</collections>",
            "</item>"
        ))
    )

Now the field <date-loaded> can have multiple values like this:

<date-loaded>2020-01-01</date-loaded>
<date-loaded>2020-01-02</date-loaded>
<date-loaded>2020-01-03</date-loaded>

Here the order is important. How should I change this query in a correct one that retrieves all the values of date-loaded and put them each in a separate XML element?


Solution

  • Things would be easier and more simple if you weren't creating a string to parse as XML, but leveraged the XQuery language to do it for you:

    for $uri in tokenize($uris,';')
    let $doc := fn:doc($uri)
    return 
      xdmp:gzip(<item>
                  <uri>{$uri}</uri>
                  {$doc/date-loaded} 
                  <collections>{string-join(xdmp:document-get-collections($uri), ";") }</collections>
                </item>)
    

    And if you wanted those date-loaded elements listed in a particular order instead of document-order from the source, you could sort them in a FLOWR:

    { 
      for $date in $doc/date-loaded
      order by $date
      return $date
    }