drakon
drakon

Reputation: 165

XSLT value-of with multiple children of different types

why do I get with that data:

<A>
  <B>block 1</B>
  <B>block 2</B>
  <C>
    no
  </C>
  <B>block 3</B>
</A>

and this transformation:

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

<xsl:template match="A/B">
  <xsl:value-of select="."/> <br/>
</xsl:template>

</xsl:stylesheet>

the following output:

block 1
block 2
no block 3

I'd expect it to be:

block 1
block 2
block 3

So: Why does the C block getting included?

//EDIT Tested with the thing here: http://www.ladimolnar.com/JavaScriptTools/XSLTransform.aspx

Upvotes: 0

Views: 161

Answers (1)

Jim Garrison
Jim Garrison

Reputation: 86774

Because of the Default Template Rules.

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

The XSL processor examines each node in turn, looking for a matching template. If it doesn't find one, it uses the default template, which just outputs the text. In your case the following happens ("no match" means no match in your stylesheet):

/A         no match, apply-templates (default element template)
/A/B       match, output text
/A/B       match, output text
/A/C       no match, apply-templates
/A/C/text  no match, output text (default text template)
/A/B       match, output text

To skip the path /A/C just add an empty template

<xsl:template match="A/C"/>

This will match the unwanted element and suppress output.

Upvotes: 1

Related Questions