Her*_*nán 5 html tags select xpath
我没有找到一种明确的方法来选择<a></a>HTML文件中两个锚点(标记对)之间存在的所有节点.
第一个锚具有以下格式:
<a href="file://START..."></a>
Run Code Online (Sandbox Code Playgroud)
第二锚:
<a href="file://END..."></a>
Run Code Online (Sandbox Code Playgroud)
我已经验证了可以使用starts-with选择两者(请注意我使用的是HTML Agility Pack):
HtmlNode n0 = html.DocumentNode.SelectSingleNode("//a[starts-with(@href,'file://START')]"));
HtmlNode n1 = html.DocumentNode.SelectSingleNode("//a[starts-with(@href,'file://END')]"));
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,以及我的业余XPath技能,我编写了以下表达式来获取两个锚点之间的所有标记:
html.DocumentNode.SelectNodes("//*[not(following-sibling::a[starts-with(@href,'file://START0')]) and not (preceding-sibling::a[starts-with(@href,'file://END0')])]");
Run Code Online (Sandbox Code Playgroud)
这似乎工作,但选择所有HTML文档!
我需要,例如对于以下HTML片段:
<html>
...
<a href="file://START0"></a>
<p>First nodes</p>
<p>First nodes
<span>X</span>
</p>
<p>First nodes</p>
<a href="file://END0"></a>
...
</html>
Run Code Online (Sandbox Code Playgroud)
删除两个锚点,三个P(当然包括内部SPAN).
有什么办法吗?
我不知道XPath 2.0是否提供了更好的方法来实现这一目标.
*编辑(特殊情况!)*
我还应该处理以下情况:
"在X和X'之间选择标签,其中X是<p><a href="file://..."></a></p>"
所以代替:
<a href="file://START..."></a>
<!-- xhtml to be extracted -->
<a href="file://END..."></a>
Run Code Online (Sandbox Code Playgroud)
我也应该处理:
<p>
<a href="file://START..."></a>
</p>
<!-- xhtml to be extracted -->
<p>
<a href="file://END..."></a>
</p>
Run Code Online (Sandbox Code Playgroud)
再一次非常感谢你.
使用此XPath 1.0表达式:
//a[starts-with(@href,'file://START')]/following-sibling::node()
[count(.| //a[starts-with(@href,'file://END')]/preceding-sibling::node())
=
count(//a[starts-with(@href,'file://END')]/preceding-sibling::node())
]
Run Code Online (Sandbox Code Playgroud)
或者,使用此XPath 2.0表达式:
//a[starts-with(@href,'file://START')]/following-sibling::node()
intersect
//a[starts-with(@href,'file://END')]/preceding-sibling::node()
Run Code Online (Sandbox Code Playgroud)
XPath 2.0表达式使用XPath 2.0 intersect运算符.
XPath 1.0表达式使用Kayessian(在@Michael Kay之后)公式用于两个节点集的交叉连接:
$ns1[count(.|$ns2) = count($ns2)]
Run Code Online (Sandbox Code Playgroud)
使用XSLT进行验证:
这个XSLT 1.0转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
" //a[starts-with(@href,'file://START')]/following-sibling::node()
[count(.| //a[starts-with(@href,'file://END')]/preceding-sibling::node())
=
count(//a[starts-with(@href,'file://END')]/preceding-sibling::node())
]
"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的XML文档时:
<html>...
<a href="file://START0"></a>
<p>First nodes</p>
<p>First nodes
<span>X</span>
</p>
<p>First nodes</p>
<a href="file://END0"></a>...
</html>
Run Code Online (Sandbox Code Playgroud)
产生想要的,正确的结果:
<p>First nodes</p>
<p>First nodes
<span>X</span>
</p>
<p>First nodes</p>
Run Code Online (Sandbox Code Playgroud)
这个XSLT 2.0转换:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
" //a[starts-with(@href,'file://START')]/following-sibling::node()
intersect
//a[starts-with(@href,'file://END')]/preceding-sibling::node()
"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于同一XML文档(上面)时,再次产生完全想要的结果.
| 归档时间: |
|
| 查看次数: |
2222 次 |
| 最近记录: |