Xpath:过滤掉孩子

时间:2011-03-03 11:17:12

标签: xpath filter nodes

我正在寻找过滤掉某些孩子的xpath表达式。子项必须包含其中包含B的CCC节点。

来源:

<AAA>
    <BBB1>
        <CCC>A</CCC>
    </BBB1>       
    <BBB2>
        <CCC>A</CCC>
    </BBB2>
    <BBB3>
        <CCC>B</CCC>
    </BBB3>
    <BBB4>
        <CCC>B</CCC>
    </BBB4>
</AAA>

这应该是结果:


<AAA>
    <BBB3>
        <CCC>B</CCC>
    </BBB3>
    <BBB4>
        <CCC>B</CCC>
    </BBB4>
</AAA>

希望有人可以帮助我。

4 个答案:

答案 0 :(得分:4)

XPath是XML文档的查询语言。因此,它只能从现有的XML文档选择节点 - 它无法修改XML文档或创建新的XML文档

使用XSLT转换XML文档并从中创建新的XML文档。

在这种特殊情况下

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*/*[not(CCC = 'B')]"/>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<AAA>
    <BBB1>
        <CCC>A</CCC>
    </BBB1>
    <BBB2>
        <CCC>A</CCC>
    </BBB2>
    <BBB3>
        <CCC>B</CCC>
    </BBB3>
    <BBB4>
        <CCC>B</CCC>
    </BBB4>
</AAA>

产生了想要的正确结果:

<AAA>
   <BBB3>
      <CCC>B</CCC>
   </BBB3>
   <BBB4>
      <CCC>B</CCC>
   </BBB4>
</AAA>

答案 1 :(得分:1)

要选择所有所需的元素和文本节点,请使用此XPATH:

//node()[.//CCC[.='B']
      or self::CCC[.='B']
      or self::text()[parent::CCC[.='B']]]

这可以通过更简单/更容易地使用具有修改的身份转换XSLT的XPATH来实现:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" />

    <!--Empty template for the content we want to redact -->
    <xsl:template match="*[CCC[not(.='B')]]" />

    <!--By default, copy all content forward -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

答案 2 :(得分:0)

试试这个,

         "//CCC[text() = 'B']"

它将为所有CCC节点提供innertext为B。

答案 3 :(得分:0)

如果你想获得AAA,BBB3和BBB4,你可以使用以下

//*[descendant::CCC[text()='B']]

如果只有BBB3和BBB4那么

//*[CCC[text()='B']]