I'm using Altova XMLSpy and I'm having trouble with the Xpath tokenize()
function using Xpath 2.0.
I have an XML containing this tag which contains the value I need:
<REF TyCd="INVREF2">VVQFAR CIG ZA5180AAB6</REF>
This is the Xpath I made to retrieve the value I need:
if (index-of(tokenize(/InvoiceMsg/INVOICE/REFS/REF[@TyCd='INVREF2'], ' '), 'CIG') > 0)
then
tokenize(/InvoiceMsg/INVOICE/REFS/REF[@TyCd='INVREF2'], ' ')[index-of(tokenize(/InvoiceMsg/INVOICE/REFS/REF[@TyCd='INVREF2'], ' '), 'CIG') + 1]
else
''
The error occurs in the third use of the tokenize()
function and says:
Unexpected 'atomic' item xs:string Details XPTY0020: The context item in an axis step must be a node
Moreover, if i use a fixed string, like this
tokenize(/InvoiceMsg/INVOICE/REFS/REF[@TyCd='INVREF2'], ' ')[index-of(tokenize('VVQFAR CIG ZA5180AAB6', ' '), 'CIG') + 1]
the error does not occur.
The question is: why error occurs only there (and not in the if statement, for example) and what can I do?
tokenize() returns a sequence of strings, so in a predicate applied to the result of tokenize(), the context item is a string. You can't use a path expression when the context item is a string. You need to bind a variable externally, and use this in the predicate: [index-of(tokenize($root/InvoiceMsg/....)]
Even better, bind a variable to the result of tokenize(/InvoiceMsg/INVOICE/REFS/REF[@TyCd='INVREF2']
since you use the expression more than once.
However, this is problematic in XPath 2.0 which has no "let" expression. If you have XPath 3.0/3.1 you can bind a variable using "let". If not, you only have "for", which only allows you to bind a singleton:
for $root in /
return ..... [index-of(tokenize($root/InvoiceMsg/....)]