我正在尝试创建一个XPath,以便选择一个节点列表并另外过滤一些数据,例如
<A>
<B type="typea">
<data>
<nodea>a</nodea>
<nodeb>b</nodeb>
<nodec>c</nodec>
</data>
</B>
<B type="typeb">
<data1>
<nodea1>a1</nodea1>
<nodeb1>b1</nodeb1>
<nodec1>c1</nodec1>
<noded1>d1</noded1>
</data1>
</B>
<B type="typec">
<data2>
<nodeb2>b2</nodeb2>
<nodec2>c2</nodec2>
</data2>
</B>
</A>
转换为
<B type="typea">
<data>
<nodea>a</nodea>
<nodeb>b</nodeb>
<nodec>c</nodec>
</data>
</B>
<B type="typeb">
<data1>
<nodea1>a1</nodea1>
<nodeb1>b1</nodeb1>
</data1>
</B>
<B type="typec">
<data2>
<nodeb2>b2</nodeb2>
<nodec2>c2</nodec2>
</data2>
</B>
我尝试使用/A/B[@type='typea' or @type='typeb' or @type='typec']
,但找不到过滤特定节点的子元素的方法。
有没有办法使用XPath过滤掉节点B的数据(type =“typeb”)。
答案 0 :(得分:0)
您只能使用XPath选择整个子树(无论哪个版本),不能修改它们/构造新的子树。创建新结果需要XSLT或XQuery。
使用XQuery,您可以选择要使用XQuery Update过滤和删除它们的节点(如果支持),否则您必须循环遍历节点并重新创建所有节点,但要重新删除它们。
答案 1 :(得分:0)
这不是单个XPATH,而是XSLT来做你要求的事情:
```
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:for-each select="/A/B[@type='typea' or @type='typeb' or @type='typec']">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="*[name() = 'nodec1' or name() = 'noded1']">
</xsl:template>
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates select="./*|./text()"/>
</xsl:copy>
</xsl:template>
```
请注意,您现有的XPATH用作基本选择器,然后两个模板负责处理它。第一个在XML中的任何位置nodec1
或noded1
的节点上执行“无输出”;第二个复制其他所有内容。