我有这样的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代码?
非常感谢
答案 0 :(得分:1)
XPath永远不会修改它选择的节点,它只是选择它们。如果您的选择包括(比方说)Root元素,那么在序列化时它将包含输入文档的所有元素,即使您只选择该单个元素。
您可以通过
遍历其祖先或自身轴上没有child21的所有元素//*[not(ancestor-or-self::child21)]
但是如果你想生成显示的结果,这不是很有用。
使用xslt过滤掉该元素及其后代是微不足道的,只需拥有一个标识模板并添加一个模板
<xsl:template match="child21"/>
丢弃输入的那个分支,但是你不能单独使用XPath。
答案 1 :(得分:0)
要排除child21
/Root/*/*[not(local-name()='child21')]
这将结果显示为
child11
child22
child31
根据您的要求进行修改。
答案 2 :(得分:0)
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>