Matteo Negrini
Matteo Negrini

Reputation: 27

Altova XMLSpy - Xpath "Unexpected 'atomic' item xs:string" error from tokenize() function

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?

Upvotes: 0

Views: 493

Answers (1)

Michael Kay
Michael Kay

Reputation: 163262

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/....)]

Upvotes: 1

Related Questions