选择使用XPath删除/过滤子元素的列表

时间:2014-02-28 18:44:58

标签: xml xpath

我正在尝试创建一个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”)。

2 个答案:

答案 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中的任何位置nodec1noded1的节点上执行“无输出”;第二个复制其他所有内容。