getodk / xforms-spec

The XForms-derived specification used in the ODK ecosystem. If you are interested in building a tool that is compliant with the forms rendered by ODK tools, this is the place to start. ✨⚒✨
https://getodk.github.io/xforms-spec/
30 stars 26 forks source link

Spec indicates that XPath node unions are supported but it seems that they aren't #293

Open lindsay-stevens opened 2 years ago

lindsay-stevens commented 2 years ago

I'm not sure if the solution is to change the spec, or to implement this support. So for now it's just a problem statement!

As stated here:

All XPath 1.0 operators are supported, i.e. |, and, or, mod, div, =, !=, <=, <, >=, >, +, -.

Create a XLSForm like so (note the escaped pipe is new syntax not yet in pyxform):

| survey     |      |      |       |                |
|            | type | name | label | default        |
|            | text | q0   | Q0    | ../t2 \| ./t4  |

Which generates this XForm:

<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms" xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <h:head>
    <h:title>pyxform_autotesttitle</h:title>
    <model odk:xforms-version="1.0.0">
      <instance>
        <test id="test">
          <q0/>
          <meta>
            <instanceID/>
          </meta>
        </test>
      </instance>
      <bind nodeset="/test/q0" type="string"/>
      <setvalue event="odk-instance-first-load" ref="/test/q0" value="../t2 | ./t4"/>
      <bind jr:preload="uid" nodeset="/test/meta/instanceID" readonly="true()" type="string"/>
    </model>
  </h:head>
  <h:body>
    <input ref="/test/q0">
      <label>Q0</label>
    </input>
  </h:body>
</h:html>

Give the XForm to ODK Validate and it says:

>> Something broke the parser. See above for a hint.
org.javarosa.xpath.XPathUnsupportedException: XPath evaluation: unsupported construct [nodeset union operation]

The error comes from the Javarosa union expression handler.

Dimagi/CC does the same thing and their spec doc says the same thing (union supported).

ODK Collect docs allude to unions here:

Nodesets can also be created by joining two or more nodes with pipes: /data/age | /data/name.

Only reference I could find about union support was in relation to adding the randomize functions: https://github.com/getodk/javarosa/issues/273