-
Notifications
You must be signed in to change notification settings - Fork 5
Description
When calling evaluateXPath in fontoxpath and the query points to a non-existing xml node, fontoxpath will return an "empty sequence" represented by an empty array.
Example:
const testXML = `
<invoice>
<id>R-12345</id>
<sum>99.50</sum>
<notes>
<note>Important note</note>
<note>Urgent!</note>
</notes>
</invoice>`;
const dom = new DOMParser().parseFromString(testXML, 'text/xml');
const xpathQuery1 = '/invoice/id[@scheme]';
const result = evaluateXPath(xpathQuery1, dom);
console.log(result);-> prints [] because <id> does not have a scheme attribute
This seems to be a problem when using variables in Schematron, which point to optional values. It seems like the Variable class in node-schematron is storing that empty array as Variable value when the node requested by a query is non-existant. This leads to problems when using the value of that variable later with string-length:
Example schematron which will fail:
<pattern>
<rule context="/invoice/id">
<let name="scheme" value="@scheme"/>
<assert test="string-length($scheme)=0">Value of '@schemeID' must not be defined.</assert>
</rule>
</pattern>--> If this check will be done on the invoice-xml shown above, this will cause an error XPTY0004 Unable to cast argument of type array(*) to type xs:string? while calling string-length. This is the exact same error which I would get if I try to call the following in fontoxpath.
const xpathQuery1 = 'string-length([])'; // Write the empty Array of the variable to the query
const result = evaluateXPath(xpathQuery1, dom);The following version works perfectly fine:
const xpathQuery1 = 'string-length(/invoice/id[@scheme])'; // Directly use the xPath without variable
const result = evaluateXPath(xpathQuery1, dom);Therefore my expectation is, that the version with the variable should actually work, too. Also this source (https://www.data2type.de) explains that string-length will return 0 if the query points to an non-existing node.
An easy workaround for this issue would be to store null inside the variable when getting an empty sequence back instead of []. This would at least solve the issue with string length because 'string-length(null)' works perfectly fine. But I don't know whether this would cause issues in other places...
I know that this issue could easily be solved by changing the Schematron to a "less-weird" implementation, but as I'm using some official Schematron to validate my xml, I don't want to temper with that Schematron file.
Thanks a lot in advance for having a look into that :)