ODK XForms spec proposal: introduce a virtual instance for metadata

I had a thought... could we leverage this model as a means to access device-specific data? eg have a 'special' instance name - instance('device') - which could expose device metadata/settings; eg deviceid, subscriberid, simserial, ...

Other XForms clients (eg Survey123) appear to expose this stuff via a custom XPath function (property(...)). But there seems to some appeal to leveraging this new, universal, XPath external instance technique (with full XPath query support as a bonus) to access 'external data' - which arguably this device metadata is.

Thoughts?

1 Like

I've taken the liberty of pulling this out to a separate proposal because it's not related to pulldata.

See history of property() and why it's not part of the ODK XForms spec anymore: https://github.com/opendatakit/xforms-spec/issues/57

Agreed using a virtual external secondary instance would be a great way to replace preloads and that's something @martijnr has mentioned a couple of times. "Virtual" refers to the fact that there may or may not be an actual XML document behind the scenes. We've started moving towards something like this with the addition of jr://instance/last-saved.

1 Like

Precisely my thought - if we're already going to start supporting psuedo secondary instances, this might be a mechanism to go back and cleanup some earlier 'hacks' (eg preloads), in a more orthogonal, uniform manner.

2 Likes

Yes, great. A set of steps, for your comments:

  1. agree on a URI for this instance
  2. agree on XML structure
  3. update pyxform (id attribute is open, but try to avoid collisions, same as with instance/last-saved)
  4. remove preloads from XForms spec, and replace with description of session instance, and examples of generating instanceID, deprecatedID, timeStart, timeEnd with actions/events.
  5. keep supporting old preloaders (but undocumented). Fwiw, Enketo would generate a session instance automagically for old forms (ie. without definition in XForm), and translate old preload syntax into reading a value from instance("__session")/path/to/node. It actually has been doing this for a while already.

For 1, how about jr://instance/session for the URI (exactly as CommCare)?
For 2, this is what we're using in Enketo (internally, so can easily be changed), also mostly copied from CommCare:

<session>
    <context>
         <deviceid/>
         <username/>
         <email/>
         <phonenumber/>
         <simserial/>
         <subscriberid/>
    <context>
</session>
1 Like

Thank you, @martijnr!

All that sounds good to me. I don't feel particularly strongly one way or another about session. I think in 3, we'll want pyxform to accept timeStart, timeEnd, etc but convert them to actions/events. As we've done with other similar changes, I'd like to ask that 3 be done a while after 1, 2, 4 and 5 so that users of older clients can have time to update before forms start using new features. This is particularly sensitive because users rely on these values being populated.

As part of this, could we also consider adding more metadata elements that users have asked for? The big one I can think of is some kind of client identifier/user agent (e.g. "Enketo 7 Windows 3.1 Firefox", "Collect 1.21.1 Android 7.1").

1 Like