Beginner's question here:
Given the following XML excerpt:
<root>
<element>
<child1>a</child1><child2>b</child2><child3>c</child3>
</element>
</root>
When I'm at the child3
context, I can use preceding-sibling::*
to get the child2
node. All right.
In the following XML excerpt:
<root>
<element child1="a" child2="b" child3="c">
</element>
</root>
When I'm at the child3
context, is it right that there is no axis in XPath 1.0 to get the child2
attribute node? I think I'd need something like preceding-sibling-attribute::
that is not available.
As a side question, is this possible with XPath 2?
It's true that there is no single axis to get from one attribute to another, but of course you can get there by chaining axes.
Attributes are not considered siblings, because they are not considered 'children' of the parent element, in the data model XPath uses. That's one reason why preceding-sibling::
won't work. It also means that attribute names such as child1
, child2
etc. are misleading in that attributes are not "children".
The other reason preceding-sibling::
won't work is that the order of attributes of a given element is undefined (implementation-dependent). Attributes must be listed in some order in a given serialization (e.g. in a file), but that file could be parsed and output again with the attributes in a different order, and it would still be considered the same document from an XML info model point of view. Therefore, there is no such thing as the "previous" or "preceding" attribute in XML.
To get the value of the child2
attribute from the context of the child3
attribute, you can use one of these depending on how you know which attribute you want...
../@child2
"The attribute named child2
of the parent element"
../@*[name() != name(current())]
"The other attributes of the parent element (not this one)"
You could even try
../@*[2]
but the results would not be predictable in general, since the order of attributes is undefined.
If the attribute names include an index component (1, 2, 3) as in your example, you could replace the number in name(current())
with a smaller number.
To answer your side question, it depends on how your requirement is defined. If the requirement is "select the previous attribute", then no, that concept is not defined in XPath 2 either.