Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain how xml is processed by xsl [closed]

Tags:

xml

xslt

I have this *.xml file

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xq340.xsl"?>

<wine grape="Cabernet">
    <winery>Duckpond</winery>
    <product>Merit Selection</product>
    <year>1996</year>
    <price>11.99</price>
</wine>

and this *.xsl file

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

<xsl:template match="winery">
    <b><font size="10pt"><xsl:apply-templates/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="../@grape"/></font></b><br/>
</xsl:template>

<xsl:template match="product">
    <i><font size="10pt"><xsl:apply-templates/></font></i><br/>
</xsl:template>

<xsl:template match="year | price">
    <font size="10pt"><xsl:apply-templates/></font><br/>
</xsl:template>
</xsl:stylesheet>

and somehow this is the output

Duckpond Cabernet
Merit Selection
1996
11.99

This is probably a lot, but I don't understand how the xsl steps through the xml to produce the html.

I would think it goes this way; the first template matches "winery", then it writes the bold and font tags. Here's where I get lost, the next instruction is "apply-templates" and this would activate the product template, write the italic tag and then "apply-templates" and write the font tags for year and price. In my "book" I should get something like this:

<b>
    <font size="10pt">
        <i>
            <font size="10pt">
                <font size="10pt">
                    <font size="10pt"></font>
                    <br/>
                </font>
            </font>
        </i>
        <br/>
    </font>
</b>
<br/>

There also the "select="../@grape" which I assume is the one it's getting the actual xml nodes values; however, this is the name of and entire xml node, so I don't really know what it's getting.

Here're my questions:

  1. How does the first "apply-templates" returns "Duckpond"?
  2. When the first "apply-templates" in winery is called is it also trying to match itself again or does it try to match ALL OTHER templates or only templates showing after?
  3. When the first template end tag </xsl:template> is hit, are the other two templates "product" and "year | price" called again?

Thanks. I guess I'm having problems trying to understand the flow of it all.

like image 696
user2368631 Avatar asked Jul 18 '26 18:07

user2368631


1 Answers

A potentially overlooked detail of XSLT is that there are built-in templates. One built-in template is defined in the standard somewhere but basically says (among other things) to always copy text nodes directly to the output. So this is where you've stumbled: the first xsl:apply-templates triggers this standard template, and this is what produces the word "Duckpond" in the output. Check it out by removing the xsl:apply-templates there. "Duckpond" disappears. (It's informative, I think, to look at the no-op XSL transform.)

You actually have what xsl:apply-templates does kind of backwards. It doesn't tell XSLT to go run a bunch of templates. xsl:call-template does that. Instead, it basically says "from where we are right now, run whatever templates you know that seem to match." Where you are at that first moment is inside the winery tag. What's under there? Nothing but a text node containing Duckpond.

Regarding your third question, what the other two templates are really doing is replacing the built-in template for those element types. XSLT is going to encounter them as it does its normal traversal (see the default template). When it finds them normally, it would just dump out their text (try it—comment out those templates). These templates cause it to instead set up some formatting first around them.

XSLT is, by default, already going to walk through the entire document. So you don't have to tell it how to do that procedurally. This is why they call it a declarative language. You can instead sort of tell it what to do when it finds something you are concerned about, and not worry as much about how it gets there.

If you want more control, you can basically override the standard template, and make your first template match /.

like image 148
Daniel Lyons Avatar answered Jul 21 '26 23:07

Daniel Lyons