tags:

views:

4962

answers:

1

Say I have this piece of xml:

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

How do I select all the child nodes of <AA> that have `bar' as its contents? In the example above, I'd want to select <CC> and <EE>. I'm thinking the solution is something like:

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

One of the simplest solutions to the OP's question is the following XPath expression:

      /*/*[.='bar']

Do note, that no XSLT instruction is involved -- this is just an XPath expression, so the question could only be tagged XPath.

From here on, one could use this XPath expression in XSLT in various ways, such as to apply templates upon all selected nodes. For example, below is an XSLT transformation that takes the XML document and produces another one, in which all elements - children of <AA> whose contents is not equal to "bar" are deleted:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <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>

When this transformation is applied on the original XML document:

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

the wanted result is produced:

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

Do note that as a match pattern we typically do not need to specify an absolute XPath expression, but just a relative one, so the full XPath expression is naturally simplified to this match pattern:

      *[. = 'bar']

Dimitre Novatchev
Thanks! Your other post was helpful as well, as the next extension would be using regular expressions for the selection:http://stackoverflow.com/questions/539781/xpath-search-based-on-dynamic-regular-expressions
zhen
@zhen You are welcome. Only keep in mind that the RegEx solution is in XPath 2.0 -- there isn't such convenient way to do this in XPath 1.0
Dimitre Novatchev