bog
bog

Reputation: 1323

Abbreviated syntax in XPath

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

Answers (2)

Mathias Müller
Mathias Müller

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

Matt Hogan-Jones
Matt Hogan-Jones

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

Related Questions