Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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