如何使用XPath选择两个节点之间的所有元素
本文关键字:之间 节点 元素 两个 XPath 何使用 选择 | 更新日期: 2023-09-27 18:26:15
如何选择第一个和第二个h2之间的所有节点(所有可能的节点)?它们之间可以有n节点,也可以有mh2标签。
节点不一定包含在HTML elment中,所以选择器可以获取所有节点。
<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>
我只是被XPath弄湿了脚。请帮助我的新手问题:)
非常感谢!
选择所需元素的一个XPath表达式是:
/*/h2[1]
/following-sibling::p
[count(. | /*/h2[2]/preceding-sibling::p)
=
count(/*/h2[2]/preceding-sibling::p)
]
通常,在这种情况下,可以使用Kayessian公式进行集合交集:
$ns1[count(.|$ns2) = count($ns2)]
此XPath表达式选择同时属于节点集$ns1
和$ns2
的所有节点。
如果要获取两个给定节点$n1和$n2之间的所有节点,这是两个节点集的交集:$n1/following-sibling::node()
和$n2/preceding-sibling::node()
。
只需将这些表达式替换为Kayessian公式,就可以得到所需的XPath表达式。
在XPath2.0中,当然会使用<<
或>>
运算符,类似于:
/*/h2[1]/following-sibling::p[. << /*/h2[1]/]
不确定xpath,但您有一个标签C#4.0,因此以下代码可以完成任务:
XElement.Parse(xml)
.Element("h2")
.ElementsAfterSelf()
.TakeWhile(n => n.Name != "h2")
.ToList()
类似的东西应该可以工作(但不使用XPath)
XmlReader reader = XmlReader.Create(new StringReader(xmlString));
if (reader.ReadToDescendant("h2"))
{
reader.Skip();
while (reader.Name != "h2")
{
//Handle nodes
reader.Read();
}
}
我知道这不是一个有效的例子,但它几乎已经存在了,
你真正需要做的就是修复语法错误,并可能修复递归项
<?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>