根据内容选择子节点

时间:2009-04-05 07:32:47

标签: xml xslt xpath nodes

XML片段:

<AA>
  <BB>foo</BB>
  <CC>bar</CC>
  <DD>baz</DD>
  <EE>bar</EE>
</AA>

如何选择<AA>作为其内容的bar的所有子节点?在上面的示例中,我想要选择<CC><EE>。我认为解决方案是这样的:

<xsl:template match="AA">
  <xsl:for-each select="???" />
</xsl:template>

1 个答案:

答案 0 :(得分:27)

OP问题最简单的解决方案之一是以下XPath表达式

*/*[.='bar']

请注意,不涉及XSLT指令 - 这只是一个XPath表达式,所以问题只能标记为XPath。

从现在开始,可以通过各种方式在XSLT中使用此XPath表达式,例如在所有选定节点上应用模板

例如,下面是一个XSLT转换,它接受XML文档并生成另一个转换,其中所有元素 - 内容不等于<AA>的{​​{1}}子元素都将被删除:

"bar"

将此转换应用于原始XML文档

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

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

    <xsl:template match="AA">
      <xsl:copy>
         <xsl:apply-templates select="*[. = 'bar']"/>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

生成了想要的结果

<AA>
    <BB>foo</BB>
    <CC>bar</CC>
    <DD>baz</DD>
    <EE>bar</EE>
</AA>

请注意

在匹配模式中,我们通常不需要指定绝对XPath表达式,而只需指定相对的表达式,因此完整的XPath表达式自然简化为此匹配模式:

<AA>
   <CC>bar</CC>
   <EE>bar</EE>
</AA>