What is the difference between using "../" and "parent" in an XPath query?

What is the difference between using "../" and "parent" to get the parent node in an XPath request. I thought they were synonyms.

Given the following two XPath queries, is there a difference between the two?

//Node/id[@type='image']/id[@attr1='myVal']/../../* //Node/id[@type='image']/id[@attr1='myVal']/parent::*/parent::* 

I am working on a C # / ASP.net application and using the first XPath request, I actually return the first brother preceding the node element. I am looking for a node element and all its children. The second XPath query will give me the expected result.

I wonder why there is a difference.

+4
source share
2 answers

Quick response; yes, .. / and parent :: * are equivalent, but you get different results because your XPath expressions are different.

Longer answer;

The expressions parent :: node () and .. are equivalent, the latter is an abbreviated form of the former according to the W3C XPath Recommendation .

You will get similar behavior from parent :: *, because XML forms a tree, so any child can have at most one parent.

The reason you get different results is because of different requests. The first has an extra * at the end (../../*), which probably returns a sequence of children of your Node.

The second gets exactly the parent element of the parent of the context node (in abbreviated form .. / ..), which is your node element of interest.

Example:

For a document

 <?xml version="1.0" encoding="UTF-8"?> <root> <Node> <id type="image"> <id attr1="myVal"> </id> </id> </Node> </root> 

Inquiries

 //Node/id[@type='image']/id[@attr1='myVal']/../../* 

and

 //Node/id[@type='image']/id[@attr1='myVal']/parent::*/parent::*/* 

return node id [@type = 'image']

While requests

 //Node/id[@type='image']/id[@attr1='myVal']/../.. 

and

 //Node/id[@type='image']/id[@attr1='myVal']/parent::*/parent::* 

return node Node.

+5
source

You do not get the same set of results, because * your expressions are not equivalent to each other. *

Consider:

1. The grandson of the target node

// Node / identifier [@ type = 'Image'] / identifier [@ attr1 = 'myVal']

2. Target child node (grandson's parent) (equivalent to exprs)

// Node / identifier [@ type = 'Image'] / identifier [@ attr1 = 'myVal'] / ..

// Node / identifier [@ type = 'Image'] / identifier [@ attr1 = 'myVal'] / parent :: *

3. Target node (grandparent of grandchild) (equivalent to exprs)

// Node / identifier [@ type = 'Image'] / identifier [@ attr1 = 'myVal'] /../ ..

// Node / id [@type = 'image'] / id [@ attr1 = 'myVal'] / parent :: * / parent :: * <- * * * YOUR 2ND EXPR * * *

4. All node child objects (equivalent expressions)

// Node / id [@type = 'image'] / id [@ attr1 = 'myVal'] /../../* <- * * * YOUR 1ST EXPR * * *

// Node / identifier [@ type = 'Image'] / identifier [@ attr1 = 'myVal'] / parent :: * / parent :: * / *


Try the equivalent of your expressions (for example, "// parent / child [@ id =" 2 "] / grandchild [@ id =" 2.1 "] /../../*" on the XPath test bench below. It is highlighted in red whose nodes correspond to the different XPath expressions that you feed it.

http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

+5
source

Source: https://habr.com/ru/post/1285986/


All Articles