Skip to content

Wrong representation of empty sequence in variable/issue with string-length #30

@NikolaiMe

Description

@NikolaiMe

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 :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions