Xpath / descendant-or-self - Search for a node in a specific tree

I am reading about the abbreviation, ///, which is apparently a shortcut for:

'/ descendant or-I'

it is clear what to expect, say, from a simple example of such an expression, for example,

// MyNode

It will return a node list of all instances in the document found from the root from elements called "myNode".

However, what is the meaning of a more complex expression, for example:

// Anode // MyNode

?

Since // (the shortcut for '/ descendant-or-self') matches the root of the node twice does this mean that the first part of the expression // // aNode is redundant and only adds to the time it takes to complete the expression (after that , how are only all expressions found throughout the document, "myNode")?

Are "// myNode" and "// aNode // myNode" the same?

Finally, if I was looking for a document for an instance of node 'myNode', which was an indirect descendant of node 'interestingTree'. But I do not need an instance of node 'myNode', which is an indirect descendant of node 'nonInterestingTree', how should I do this?

for example, search in a document:

<root> <anode> <interestingTree> <unknownTree> <myNode/><!-- I want to find this one, not the other, where I don't know the path indicated by 'unknownTree' --> </unknownTree> </interestingTree> <nonInterestingTree> <unknownTree> <myNode/> </unknownTree> </nonInterestingTree> </anode> <anode> <someOtherNode/> </anode> </root> 

Thanks!

+4
source share
2 answers

Are '// myNode' and '// aNode // myNode' the same?

Yes, in this case, since all myNodes are also descendants of anode . However, in the general sense, //aNode//myNode obviously does not correspond to nodes that do not have anode parent in their ancestor tree.

xpath:

 //aNode//myNode 

will ignore any intermediate hierarchy between anode and myNode , i.e. it will match /aNode/myNode , /anyNodes/anode/myNode and /anyNodes/anode/xyzNode/myNode

Which answers your last question, you can find the nodes in an interesting approach like this: (and again, ignoring any intermediate elements in the hierarchy)

 //anode//interestingTree//myNode 

Ideally, of course, you should be as clear as possible in your path, as // can incur overhead on performance due to the potentially large number of elements that need to be performed to search.

Edit Maybe this helps?

I changed your xml input for clarity to:

 <root> <anode> <interestingTree> <unknownTree> <myNode> MyNode In Interesting Tree </myNode> </unknownTree> </interestingTree> <nonInterestingTree> <unknownTree> <myNode> MyNode In Non-Interesting Tree </myNode> </unknownTree> </nonInterestingTree> </anode> <anode> <someOtherNode/> </anode> <bnode> <myNode> MyNode in BNode </myNode> </bnode> </root> 

When analyzing through a stylesheet:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> Matched by `//myNode` <xsl:apply-templates select="//myNode"> </xsl:apply-templates> Matched by `//aNode//myNode` <xsl:apply-templates select="//anode//myNode"> </xsl:apply-templates> Matched by `//aNode//interestingTree//myNode` <xsl:apply-templates select="//anode//interestingTree//myNode"> </xsl:apply-templates> </xsl:template> <xsl:template match="myNode"> <xsl:value-of select="text()"/> </xsl:template> </xsl:stylesheet> 

Returns the following:

 Matched by `//myNode` MyNode In Interesting Tree MyNode In Non-Interesting Tree MyNode in BNode Matched by `//aNode//myNode` MyNode In Interesting Tree MyNode In Non-Interesting Tree Matched by `//aNode//interestingTree//myNode` MyNode In Interesting Tree 
+4
source

You ask: "Are" // myNode 'and' // aNode // myNode 'will exactly match? "

Not necessary. The first returns all elements named myNode in the document; the second returns all elements named myNode that appear as descendants of elements named aNode . In your XML example, these two descriptions describe the same set, but they will not be in some XML documents.

On the other hand, the expressions //aNode//myNode and //myNode[ancestor::aNode] will always return the same set of nodes.

+1
source

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


All Articles