Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you find all nodes between two H3's using XPATH?

Tags:

How would you find all nodes between two H3's using XPATH?

like image 527
klumsy Avatar asked Sep 30 '10 23:09

klumsy


People also ask

How many nodes are there in XPath?

In XPath, there are seven kinds of nodes: element, attribute, text, namespace, processing-instruction, comment, and document nodes. XML documents are treated as trees of nodes. The topmost element of the tree is called the root element.

What is an XPath node?

Xpath Node is defined as a point where the path address initiates, as it follows a concept of nodes. In simple terms they are the individual elements of the Xpath hierarchical structure which are termed as a node and enable an XSL processing. Xpath expressions could be done with HTML and XML.

What is traversing in XPath?

Save. XPath is used to navigate in XML documents and it uses the expressions for navigation. Today I am going to discuss some key points about navigation(traversing) in XML Xpath. Forward Traversing: We can traverse forward in the XML XPath in the following ways.


1 Answers

In XPath 1.0 one way to do this is by using the Kayessian method for node-set intersection:

$ns1[count(.|$ns2) = count($ns2)] 

The above expression selects exactly the nodes that are part both of the node-set $ns1 and the node-set $ns2.

To apply this to the specific question -- let's say we need to select all nodes between the 2nd and 3rd h3 element in the following XML document:

<html>   <h3>Title T31</h3>     <a31/>     <b31/>   <h3>Title T32</h3>     <a32/>     <b32/>   <h3>Title T33</h3>     <a33/>     <b33/>   <h3>Title T34</h3>     <a34/>     <b34/>   <h3>Title T35</h3> </html> 

We have to substitute $ns1 with:

/*/h3[2]/following-sibling::node() 

and to substitute $ns2 with:

/*/h3[3]/preceding-sibling::node() 

Thus, the complete XPath expression is:

/*/h3[2]/following-sibling::node()              [count(.|/*/h3[3]/preceding-sibling::node())              =               count(/*/h3[3]/preceding-sibling::node())              ] 

We can verify that this is the correct XPath expression:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output omit-xml-declaration="yes" indent="yes"/>   <xsl:template match="/">   <xsl:copy-of select=    "/*/h3[2]/following-sibling::node()              [count(.|/*/h3[3]/preceding-sibling::node())              =               count(/*/h3[3]/preceding-sibling::node())              ]    "/>  </xsl:template> </xsl:stylesheet> 

When this transformation is applied on the XML document presented above, the wanted, correct result is produced:

<a32/>  <b32/> 

II. XPath 2.0 solution:

Use the intersect operator:

   /*/h3[2]/following-sibling::node() intersect    /*/h3[3]/preceding-sibling::node() 
like image 191
Dimitre Novatchev Avatar answered Oct 20 '22 20:10

Dimitre Novatchev