我有一个类似的XML:
<Root xmlns:test1="http://www.test1.com" xmlns:test2="http://www.test2.com" Attr="root">
<test1:Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</test1:Child1>
<test2:Child2 Attribute2="c2">
<child21 Attribute21="c21">
<child211 />
<child212 />
<child213 />
</child21>
<child22 Attribute22="c22">Element22</child22>
</test2:Child2>
<test2:Child3 Attribute3="c3">
<child31>Element31</child31>
</test2:Child3>
</Root>
我想写一个XPath,这样我就可以选择除child21
元素及其子元素之外的所有元素。因此输出应该如下所示:
<Root xmlns:test1="http://www.test1.com" xmlns:test2="http://www.test2.com" Attr="root">
<test1:Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</test1:Child1>
<test2:Child2 Attribute2="c2">
<child22 Attribute22="c22">Element22</child22>
</test2:Child2>
<test2:Child3 Attribute3="c3">
<child31>Element31</child31>
</test2:Child3>
</Root>
这方面的xpath代码是什么?
非常感谢
XPath从不修改它选择的节点,它只是选择它们。如果您的选择包括(比如)Root元素,那么当序列化时,它将包括输入文档的所有元素,即使您只选择了一个元素。
通过,您可以迭代所有祖先或自轴中没有child21的元素
//*[not(ancestor-or-self::child21)]
但是,如果您想要生成所显示的结果,那么这并不是很有用。
使用xslt过滤掉该元素及其子元素很简单,只需有一个标识模板并添加一个单一模板
<xsl:template match="child21"/>
它丢弃了输入的那个分支,但您不能单独使用XPath。
XPath以排除child21
/Root/*/*[not(local-name()='child21')]
这给出了的结果
child11
child22
child31
根据您的要求进行修改。
XPath会选择节点,但如果您想跳过某些元素实际复制XML,您需要的是XSLT-这将产生您想要的输出:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Template to copy everything-->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- Template to skip 'child21' elements -->
<xsl:template match="child21">
</xsl:template>
</xsl:stylesheet>