我有一个xml文件:
<root>
<!-- all other kinds of xml elements including possibly other h1 -->
<dl> some text
<dt>
other text
</dt>
</dl>
<!-- all other kinds of xml elements including possibly other h1 -->
<h1>
<a>starting here</a>
</h1>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<!-- Many elements but all of them are dl -->
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<h1>
<a>Ending here</a>
</h1>
<!-- all other kinds of xml elements including possibly other h1 -->
<dl>foo
<dt>
bar
</dt>
</dl>
<!-- all other kinds of xml elements including possibly other h1 -->
</root>
现在,我想在<dl>
代码之间选择<h1>
节点(及其子节点)。
我尝试了following
,following-sibling
的各种组合,但没有成功。
任何人都可以帮助我吗?
答案 0 :(得分:0)
您可以使用以下XPath 1.0表达式查找<dl>
标记之间的<h1>
节点:
//dl[preceding-sibling::*[1] = preceding-sibling::h1[1] and following-sibling::*[1] = following-sibling::h1[1]]
这会找到<dl>
标记,其中前一个兄弟是<h1>
标记,紧接着的兄弟标记也是<h1>
标记。
根据要求,可以简化为:
//dl[preceding-sibling::h1 and following-sibling::h1]
只会在其之前或之后找到所有<dl>
标记的<h1>
标记。
请注意,您的XML需要包含一个根元素才能使其有效,并且您通常无法在无效的XML上执行XPath表达式。
答案 1 :(得分:0)
选择h1
前面有h1
//h1/following-sibling::dl[following-sibling::h1]
答案 2 :(得分:0)
以前的答案都适用于具有两个h1
标记的给定示例。
但是如果输入稍微复杂一点就行不通有三个或四个h1
标签。
如果是这样,您可以遵循这个优秀的answer。
以下是在第一个和第二个dl
代码之间获取h1
代码的修改
//h1[1]/following-sibling::dl
[count(.|//h1[2]/preceding-sibling::dl) = count(//h1[2]/preceding-sibling::dl) ]
答案 3 :(得分:0)
由于相邻dl
元素的序列必须紧跟h1
兄弟之前和之后,因此选择所有dl
元素序列的一个表达式为:
/*/dl[preceding-sibling::*[not(self::dl)][1][self::h1]
and
following-sibling::*[not(self::dl)][1][self::h1]
]
您可以使用以下表达式查找所有h1
个元素,每个元素紧接在dl
s的所需相邻序列之前:
/*/h1[following-sibling::*[1][self::dl]
and
following-sibling::*[not(self::dl)][1][self::h1]
]
您可以找到所有h1
个元素,每个元素都紧跟在dl
s的所需相邻序列之后,并带有以下表达式:
/*/h1[preceding-sibling::*[1][self::dl]
and
preceding-sibling::*[not(self::dl)][1][self::h1]
]
最后,这是一个基于XSLT的验证
此转换仅评估用于查找dl
s的所有有序序列的表达式,并将它们复制到输出中。
它还会评估选择开始和结束h1
的表达式,并输出结果。
最后,对于每对(起始h1
,结束h1
),它会计算一个XPath表达式,该表达式选择此特定组中的所有dl
并输出结果。
<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="
/*/dl[preceding-sibling::*[not(self::dl)][1][self::h1]
and
following-sibling::*[not(self::dl)][1][self::h1]
]"/>
========================
<xsl:variable name="vStartingH1s" select=
"/*/h1[following-sibling::*[1][self::dl]
and
following-sibling::*[not(self::dl)][1][self::h1]
]"/>
<xsl:copy-of select="$vStartingH1s"/>
========================
<xsl:variable name="vEndingH1s" select=
"/*/h1[preceding-sibling::*[1][self::dl]
and
preceding-sibling::*[not(self::dl)][1][self::h1]
]"/>
<xsl:copy-of select="$vEndingH1s"/>
========================
<xsl:for-each select="$vStartingH1s">
<xsl:variable name="vPos" select="position()"/>
<xsl:value-of select=
"concat(
'========== Group ', $vPos, ' ==========
')"/>
<xsl:copy-of select=
"following-sibling::*
[count(.| $vEndingH1s[position()=$vPos]/preceding-sibling::*)
=
count($vEndingH1s[position()=$vPos]/preceding-sibling::*)
]"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(提供的转换为包含两组想要的dl
):
<root>
<!-- all other kinds of xml elements including possibly other h1 -->
<a/>
<h1/>
<dl> some text
<dt>
other text
</dt>
</dl>
<!-- all other kinds of xml elements including possibly other h1 -->
<b/>
<h1/>
<h1>
<a>starting here</a>
</h1>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<!-- Many elements but all of them are dl -->
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<h1>
<a>Ending here</a>
</h1>
<h1/>
<c/>
<h1/>
<!-- all other kinds of xml elements including possibly other h1 -->
<p/>
<dl>foo
<dt>
bar
</dt>
</dl>
<!-- all other kinds of xml elements including possibly other h1 -->
<h1/>
<d/>
<h1>
<a>starting here</a>
</h1>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<h1>
<a>Ending here</a>
</h1>
<e/>
<h1/>
<f/>
产生了想要的正确结果:
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
========================
<h1>
<a>starting here</a>
</h1>
<h1>
<a>starting here</a>
</h1>
========================
<h1>
<a>Ending here</a>
</h1>
<h1>
<a>Ending here</a>
</h1>
========================
========== Group 1 ==========
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>========== Group 2 ==========
<dl>foo
<dt>
bar
</dt>
</dl>
<dl>foo
<dt>
bar
</dt>
</dl>