Reputation: 1323
What does //olist/items
return?
Well, //
is the abbreviation for descendant-or-self::node()/
so it returns a set of nodes that are descendants of my context node. After that, it must have olist
in its path.
item
means child::item
so it returns children of my context node (that is //olist/
). So, in the end it returns item nodes, children of all children of my starting context node or one of its descndants that have olist
in their path.
Right?
Upvotes: 0
Views: 975
Reputation: 22617
item means child::item so it returns children of my context node (that is //olist/). So, in the end it returns item nodes, children of all children of my starting context node or one of its descendent that have olist in their path.
Right?
That's almost correct - not only must the item
elements in the result set "olist
in their path" (which I understand as: must be a descendant of olist
) - they must be a direct child element of olist
.
Then let us clear the confusion about the "root node":
When Matt Jones uses "root node" in his explanation of //
, he does not mean the outermost element of his XML example. It is only by conincidence that the outermost element there is also called root
.
The "root node" or "document node" is different from the outermost element of an XML document. The outermost element is physically present in your document, and all XML elements and attributes are inside it.
The document node is not visible in the document, it's an abstract concept that represents an entire XML document. All nodes in an XML document are descendants of the document node.
On the other hand, not all nodes are descendants of the outermost element: for instance, there could be processing instructions or comments outside the outermost element. But those processing instructions and comments are contained by the document node.
Now, //
means either the context node or any of its descendants, as you know already. In this case, the document node will be the context of your path expression (if that's not what you want, prefix it with .
: .//
).
So the expression //item
means /descendant-or-self::node()/child::item
which means
select any element node with the name
item
that is a child of a node anywhere in the XML structure
The parent of such an item
element will either be the document node (in this case the item
element will be the outermost element) or any element node.
In XPath 1.0, the abstract container for XML documents is called "root node", from XPath 2.0 onwards it is called "document node".
XPath 1.0 Specification, Abbreviated Syntax
"Document element and root node are often confused, but they are not the same thing"
Upvotes: 3
Reputation: 3103
//olist/items
This XPath will return a collection of elements that have the name items
that are child nodes of elements that have the name olist
that are descendants of the root node of the XML document that you are querying.
In this sample XML here:
<root>
<olist>
<test/>
<items value="A"/>
</olist>
<other>
<inside>
<items value="B"/>
<olist>
<items value="C"/>
</olist>
</inside>
</other>
</root>
The //olist/items
XPath will select the items
elements with the value
attributes of A and C - because they are child elements of olist
elements.
It will not select the items
element with the value
attribute of B because that element does not have the required parent element of olist
.
Syntactically, //
means /descendant-or-self::node()/
- on the MDN it states
The descendant-or-self axis indicates the context node and all of its descendants. Attribute and namespace nodes are not included - the parent of an attribute node is an element node, but attribute nodes are not the children of their parents.
/olist
means child::olist
- the MDN definition of the child axis is
The child axis indicates the children of the context node. If an XPath expression does not specify an axis, the child axis is understood by default. Since only the root node or element nodes have children, any other use will select nothing.
Upvotes: 0