Question

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

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top