0
votes

I have an xml file which contains following:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<q>sdfsdf</q>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
</catalog>

And I have two XSL files XSL#1:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="catalog/cd/title"/>
</xsl:template>
</xsl:stylesheet>

And XSL#2:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//cd">
<xsl:value-of select="title"/>
</xsl:template>
</xsl:stylesheet>

When I use XSL#1 result is: “Empire Burlesque” but when I use XSL#2 result is: “sdfsdf Empire Burlesque”. Why does XSL#2 return such value? Is it possible to get value of child node “title” when parent node “cd” is matched?

1

1 Answers

1
votes

When you read an XSLT script, it is not enough to read what has been written.

You have also to know what has not been written, but the XSLT procesor still assumes as the default setting.

In this particular case, you probably forgot (or till now didn't know) that the default template for elements and the whole document is:

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

and the default template for text and attribute nodes (slightly simplified) is:

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

So e.g. q element (and its content) is processed by just these templates, reproducing only the text content and ignoring markup (XML tags).

If you don't want this, add e.g. an empty template matching q elements

<xsl:template match="q"/>

and the extra sdfsdf will disappear from the output.

Actually you can put instead an empty template for text nodes

<xsl:template match="text()"/>

to "suppress" the text content of all elements which your templates do not serve explicitely.