Index in array's in ADL

(: from all the items, take the first one, then take all the ones with node id at0009 :slight_smile:
/*[1][@archetype_node_id=at0009]

(: from all the items, take the first one iff it has node id at0009 :slight_smile:
/*[@archetype_node_id=at0009 and position()=1]

i.e., so two predicates in a row act like a pipeline of filters…

Exactly, that is my objection, the example is not a path/location to a leafnode, but it is a filter, the keyword “and” can be replaced by “or” and then something different comes out. Very useful in xPath, but not in leafnode-location-indicator. So as location-indicator the keyword “and” is useless, because it cannot be replaced. And that is my second objection, the use of a meaningless/useless keyword.

The purpose of the path is solely to indicate to which leafnode in an archetype a DataValue belongs.

[at0009,1]

Exactly, a comma will do, however I currently do not support this, but I use an index in square brackets [1], but I am going to change that.

So I see, for me, no reason to further discuss this, but I hope others will, and I am very interested in the outcome.

regards,
Bert

Take into account that [position()=1] is equivalent to [1] in XPath.
In fact, another thing worth noticing is that if you can assure unique
atCodes you only need to put last one. Using both XPath look like this

/cluster[@archetype_id=‘openEHR-EHR-CLUSTER.bert.v1’]/items[@archetype_node_id=‘at0008’]/value[1]/value=Jan
/cluster[@archetype_id=‘openEHR-EHR-CLUSTER.bert.v1’]/items[@archetype_node_id=‘at0008’]/value[2]/value=Peter
/cluster[@archetype_id=‘openEHR-EHR-CLUSTER.bert.v1’]/items[@archetype_node_id=‘at0009’]/value/value=Balkenende

firstly, the statement about atcodes above is right - we only need to do this [1] [2] business when there are multiple instances of the same at-code.

I agree, since we are not writing XML or xPath, but ADL paths, we can honour our own rules. In XML the archetype_node_id is just an attribute, and when you read about XML Schema, you see that the element name is very important, and attributes are often ignored in these element rules. So in XML formalism it is understandable that elements with different archetype_node_id (an attribute) can fit in the same list-array, and having the same counter-

But because we need to honour our own rules in which the archetype_node_id is very important, and two elements with same names but different archetype_node_ids cannot be in the same list-array.

Bert

It is right in XPath, maybe is less intuitive, but I would say these
are even less intuitive and still work
/cluster[@archetype_id=‘openEHR-EHR-CLUSTER.bert.v1’]/items/value[3]/value=Balkenende
/cluster[@archetype_id=‘openEHR-EHR-CLUSTER.bert.v1’]/items[3]/value/value=Balkenende

Diego,
do you mean you tested this? Could you provide the XML source content you did this on?

There is only one way to read this. In the first line in items is a list-array with at least three cells. In the second line is an array of items-cells in cluster.

Line one is illegal in the OpenEhr RM, but of couse one can write an RM in which it is possible, so, as ADL it is legal.

I think we should decide why is this for:

Is this for ADL paths? then use ADL path syntax.
Is this for XML query? then use XPath

well what we want I believe, is for the ADL paths to be easily mappable (i.e. simple algorithm) to convert to the correct Xpaths. I’m not yet convinced we have the answers right here. Happy to be corrected though.

A programmer does not look for easy mapping, in fact, how more difficult the mapping, there will be opportunity to make money.

But seriously, easy mapping, difficult mapping, who cares, there needs to be written code, one day, or one week, it will last for ever.

So easy mappable in syntax or difficult, it is just code and not very interesting.

But the mapping must be possible. Don’t try to map ADL-archetypes to XML Schema, that is not possible. That is not easy or difficult, but impossible.

But from ADL paths/queries to xPath is very well possible, and only a bit difficult.
IMHO there is no reason to change ADL path to kinda xPath.

Bert

  (: from all the items, take the first one, then take all the ones with node id at0009 :slight_smile:
  /*[1][@archetype_node_id=at0009]

  (: from all the items, take the first one iff it has node id at0009 :slight_smile:
  /*[@archetype_node_id=at0009 and position()=1]

i.e., so two predicates in a row act like a pipeline of filters...

Depending on the data you're xpathing, these may or may not have the same result, since the construct [][] is a sub-select. I believe, looking at everyone's answers, the intent of ADL paths is that most-precise third option (AND of the predicates), which is also what we've implemented previously on our SQL backend, and conceptually matches that proposal of

  [at0009,1]

this was my intention when specifying it (years ago now!).

Hey, that's great, so everything is in fact in perfect alignment :slight_smile:

(the , meaning AND I think), and that would make for an easy and unambiguous ADL path --> xpath translation.

But, those aren't the current rules, and with our xml backend, right now, we have a not so easy ADL path --> xpath translation, because people want to write

  [at0009][1]

So I am unclear why you prefer to write this? Is there some system or customer requirement?

Ahmmm...no, it's not really a requirement in and off itself, just existing use and existing implementation, and so with that the ball and chain of backward compatibility and software maintenance.

which we dutifully turn into xpath

  [@archetype_node_id=at0009][1]

which _seems_ the most spec-compatible behavior insofar as ADL paths are precisely defined -- but that does not match what people mean.

we could certainly extend the ADL path spec to allow this, it just needs to be specified as having different semantics from the above version.

If I were you, I would work on the principle that paths of the form [@archetype_node_id=at0009][1] are legal (even if I don't quite understand why you want these particular paths) and have the semantics you have explained above.

You know, if I were me I would do that too :-). In this instance the implementers perspective is actually easier than the spec/design perspective: liberal in acceptance is I guess to allow a bunch of different syntax variant and then always implement the same, sane, processing (i.e. predicate AND-ing), and from a backwards compatibility standpoint we'll probably keep producing [at0009][1].

That's basically what Bert's code does already (if it looks like an at-code, it's probably an at-code, if it looks like a number, it's probably an index, etc). I'm just continuing on with that pattern and tune it a bit during any adl-path-to-xpath assistance.

It's good to be able to say that approach aligns with the expectations and intentations here!

As for spec revision and such, it seems to me it could be a good idea to diverge a bit more explicitly from xpath (using wording such as "a lot like xpath" and "machine translatable into xpath", rather than "xpath compatible"), and allow the comma shortcut for indices, too, so you always end up with AND-ed predicates and can have one or more of

[name,at-code,archetypeNodeId,archetypeId,index]

perhaps even stating the shortcut form is considered the canonical one.

That, or bigger changes to the point you end up with readable/writeable xpath and don't need shortcuts :slight_smile:

cheers,

Leo

I'm still struggling to understand the reason of all this discussion. In
the previous example, an instance data value (not DataValue) belong to the
node [at0009], that's all even if that node has multiple occurrences. ADL
paths are used to reference object nodes within an archetype, not
instances, and in an archetype every node type is unique. A different
thing is if you are talking about ODIN/dADL paths.

The word "probably" indicates that it is not safe.

No programming-language/compiler allow a name of something to start with a number, and certainly not, be a number.
So it is very common practice to guess if a combination of characters is a number, and if it is, it cannot be a name.

Thus, the probability if something is an index of an array (always a number) or a name/atcode is 100%.

Bert

(PS: The comma to add an index inside the square brackets of an atcode only works when there is an atcode.
So this is not always the case. The square-bracket notation of an index always is possible.)

That is the case. The discussion is about how to indicate to which leafnode in an archetype datavalues belong.
Every leafnode has an unique path towards it.

In fact, the starting of the discussion was that some kernel-developers/users use path/value combinations, and not object-representing notations to handle datavalues in combination with archetype definitions.

Bert

I should not try to write English, at midnight.

Excuse me :wink:

Bert

That’s why I suggested this
/items[at0008]/value[1]/value = Jan

As David said, /items[at0008][1] and /items[at0008][2] are referencing the same node in ADL (at0008).

In my opinion, if you want to access the leaf node for the value it makes very little sense to try to reference the nearest object with atXXXX. Or in other words, If you need to tell apart two siblings I would put artificial identifiers in the nodes that don’t have any. And by the way, if you need to tell apart two sibling nodes because they have different semantics (surname 1 & surname 2) you probably want to put an identifier on those too in the first place.

well… we sort of are here. I guess the point is that it makes no sense if the runtime paths for archetyped data are not completely consistent with the pure (design-time) archetype paths, i.e. a clean superset of syntax. - thomas

Just tested it with the xml you provided. The second one works, first one doesn’t. It’s weird because in the sample data I created they did in fact work. I generated it modifying another instance you put on this thread.

Something IMPORTANT I have said before, and completely forgot due to other distractions:

There is a proposal (it's on the SPECPR issue tracker somewhere) to add a property to the LOCATABLE class called (say) sibling_id: INTEGER

which would have the effect of unambiguously numbering sibings under a container attribute in the data. In XML data I would expect to make this an attribute, so the effect on paths would be be able to say

cluster[at0009]/items[at0008, 2]

as ADL short hand for

cluster[@archetype_node_id='at0009']/items[@archetype_node_id='at0008', @sibling_id='2']

This is for next-gen openEHR obviously, so doesn't help Bert/Leo right now.

anyone have thoughts on that? Note that the position() predicate should still work, which means it can't be in its short form as [...., 2], or else the sibling_id needs a different short syntax.

Other note: sibling_id order will be the same regardless of re-ordering whereas the value of position() is whatever the physical position is.

- thomas

Something IMPORTANT I have said before, and completely forgot due to other distractions:

'should' have said before!

I am not sure about this, sibling_id is the array-index, when I understand. What happens in case a dataset changes, for example an item is removed from a cluster, in that case all the other datasets should need revisiting to have this property changed.

For my idea, the array-index is volatile and calculated at the moment of need.

Bert

Or attribute is unordered

the intention is that it would only ever be calculated once, at creation time. So it would be immutable in fact. That's the current design idea - this isn't documented anywhere properly, and others may have better ideas, so feel free to suggest them.

- thomas

Bert Verhees said> Or would another solution be better?

I suggest:

/items[at0008]/value/value = Jan Peter
/items[at0009]/value/value = Balkenende

or

CLUSTER[at0007] occurrences matches {0..1} matches {
                            ELEMENT[at0008] occurrences matches {0..*} matches { -- givenname
                                value matches {
                                    DV_TEXT matches {*}
                                }
                            }
                            ELEMENT[at0009] occurrences matches {0..*} matches { -- middlenames
                                value matches {
                                    DV_TEXT matches {*}
                                }
                            }
                            ELEMENT[at0010] occurrences matches {0..1} matches { -- familyname
                                value matches {
                                    DV_TEXT matches {*}
                                }
                            }
                        }

then

/items[at0008]/value/value = Jan
/items[at0009]/value/value = Peter van Wat
/items[at0010]/value/value = Balkenende

i.e. don't use indexes - especially where they contradict the meaning:
* How can you have two 'first' names?
* Family names come first in some asian languages.

Regards,
Colin

Thomas how do I get George's email off this list as I am getting all his
emails?

Regards and thanks,

Joe Griffiths
0422 591 263
National Engagement Manager
Joe.Griffiths@oceaninformatics.com
                                                
www.oceaninformatics.com

i.e. don’t use indexes - especially where they contradict the meaning:

  • How can you have two ‘first’ names?
  • Family names come first in some asian languages.

Hi Colin, the discussion is about syntax, not semantics, and a given archetype is assumed.

regards,

Bert

.