Search code examples
xmlxquerymarklogic

Strange Error MarkLogic searching through nodes


I have a problem within QueryConsole

When i try to run this:

xquery version "1.0-ml";
declare namespace link="http://www.xbrl.org/2003/linkbase";
declare namespace bd-alg="http://www.nltaxonomie.nl/nt11/bd/20161207/dictionary/bd-algemeen";
declare namespace bd-bedr="http://www.nltaxonomie.nl/nt11/bd/20161207/dictionary/bd-bedrijven";
declare namespace bd-bedr-tuple="http://www.nltaxonomie.nl/nt11/bd/20161207/dictionary/bd-bedr-tuples";
declare namespace bd-dim-mem="http://www.nltaxonomie.nl/nt11/bd/20161207/dictionary/bd-domain-members";
declare namespace bd-dim-dim="http://www.nltaxonomie.nl/nt11/bd/20161207/validation/bd-axes";
declare namespace xbrldi="http://xbrl.org/2006/xbrldi";
declare namespace xbrli="http://www.xbrl.org/2003/instance";
declare namespace iso4217="http://www.xbrl.org/2003/iso4217";
declare namespace xlink="http://www.w3.org/1999/xlink";

let $factValues :=
  for $doc in /xbrli:xbrl
      let $factValue := $doc//xs:QName("bd-bedr:WageTaxDebt")
      let $docId := $doc//xbrli:identifier/text()
      where $docId eq "11"
            return $factValue/text()

return $factValues

The string between the quotes is one from an input which gives only strings

I get this error :

[1.0-ml] XDMP-NOTANODE: (err:XPTY0019) $factValue/text() -- "bd-bedr:WageTaxDebt" is not a node
Stack Trace
At line 19 column 21:
In xdmp:eval("xquery version &quot;1.0-ml&quot;;&#10;&#10;declare namespace li...", (), <options xmlns="xdmp:eval"><database>11967107844575880929</database>...</options>)
$doc := fn:doc("document76.xml")/xbrli:xbrl
$factValue := ("bd-bedr:WageTaxDebt", "bd-bedr:WageTaxDebt", "bd-bedr:WageTaxDebt", ...)
$docId := fn:doc("document76.xml")/xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier/text()
17. let $docId := $doc//xbrli:identifier/text()
18. where $docId eq "11"
19. return $factValue/text()
20. 
21. return $factValues

I understand that a string is not a node, but shouldn't the cast to QName solve this?

Does anybody know what i did wrong, thank you in advance!


Solution

  • As you figured out already, you cannot write:

    let $factValue := $doc//xs:QName("bd-bedr:WageTaxDebt")
    

    XPath expressions are better written as:

    let $factValue := $doc//bd-bedr:WageTaxDebt
    

    You are after a dynamic XPath though, which makes it a bit more tricky. With plain XPath you could do:

    let $factValue := $doc//*[name() eq xs:QName("bd-bedr:WageTaxDebt")]
    

    But that is potentially very slow, particularly if your XML doc is big. A more performant way would probably be:

    let $factValue := xdmp:value("$doc//" || xs:QName("bd-bedr:WageTaxDebt"))
    

    However, that comes with a risk of code injection, so you must validate input carefully, for instance by keeping the cast to xs:QName.

    Best approach might be however, to use xdmp:unpath:

    let $factValue := xdmp:unpath("$doc//" || "bd-bedr:WageTaxDebt")
    

    HTH!