How to select all elements between two nodes using XPath

How do I choose everything (all possible nodes) between the 1st and second h2? Between them there can be n nodes, and there may be m h2 tags.

Nodes will not necessarily be contained in the HTML element, so a selector can just grab them all.

<html> <h2>asdf</h2> <p>good stuff 1</p> <p>good stuff 2</p> <p>good <a href="#">asdf</a>stuff n...</p> <h2>qwer</h2> <p>test2</p> <h2>dfgh</h2> <p>test2</p> </html> 

I'm just tired of XPath. Please help my newbie :)

Many thanks!

+4
source share
4 answers

One XPath expression that selects the required elements :

  /*/h2[1] /following-sibling::p [count(. | /*/h2[2]/preceding-sibling::p) = count(/*/h2[2]/preceding-sibling::p) ] 

In the general case, in such cases, you can use the Kaisey formula for many intersections:

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

This XPath expression selects all nodes belonging to both $ns1 and $ns2 .

If you want to get all the nodes between two given nodes $ n1 and $ n2, this will be the intersection of two nodes: $n1/following-sibling::node() and $n2/preceding-sibling::node() .

Just replace this expression with the Kayessian formula, and you have the required XPath expression.

In XPath 2.0 , of course, you can use the << or >> operator, for example:

  /*/h2[1]/following-sibling::p[. << /*/h2[1]/] 
+4
source

Not sure about xpath, but you have a C # 4.0 tag, so the following code does the job:

 XElement.Parse(xml) .Element("h2") .ElementsAfterSelf() .TakeWhile(n => n.Name != "h2") .ToList() 
+1
source

Something like this should work (doesn't use XPath)

  XmlReader reader = XmlReader.Create(new StringReader(xmlString)); if (reader.ReadToDescendant("h2")) { reader.Skip(); while (reader.Name != "h2") { //Handle nodes reader.Read(); } } 
0
source

I know this is not a working example, but it is almost there,

all you really need to do is fix syntax errors and possibly fix recursive elements

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" > <xsl:output method="xml" indent="yes"/> <xsl:template match="@* | node()"> <xsl:call-template name="tmpMatchNode"> <xsl:with-param name="indx" select="0"/> <xsl:with-param name="self" select="node()"/> </xsl:call-template> </xsl:template> <xsl:template name="tmpMatchNode" > <xsl:variable name="indx" /> <xsl:variable name="self"/> <xsl:element name="name($self[index])"> <xsl:value-of select="$self[$indx]"/> </xsl:element> <xsl:choose> <xsl:when test="$self[$indx+1]:name() != 'H2'"> <xsl:call-template name="tmpMatchNode"> <xsl:with-param name="indx" select="$indx +1"/> <xsl:with-param name="self" select="$self"/> </xsl:call-template> </xsl:when> <xsl:when test="$self[$indx]:name() = 'H2'"> <xsl:call-template name="tmpMatchNode"> <xsl:with-param name="indx" select="$indx +1"/> <xsl:with-param name="self" select="$self"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:comment>DO NOTHING HERE AS WE HAVE NOTHING TO DO</xsl:comment> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> 
0
source

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


All Articles