Pergunta

I'm studing XSLT and XML for an exam. I've this XML document:

    <?xml version="1.0" encoding="UTF-8"?>    <!-- Prologo XML -->
<?xml-stylesheet 
   type="text/xsl" href="listacd_es1.xslt"?>    <!-- Istruzione che indica il documento XSLT da associare -->

<listacd>    <!-- Nodo Principale o Elemento Radice -->
    <artista>
        <nome>Stanley Jordan</nome> 
        <albums>
            <album>
                <titolo>Magic Touch</titolo>
                <anno>1985</anno>
                <etichetta>Blue Note</etichetta>
            </album>
            <album>
                <titolo>Stolen Moments</titolo>
                <anno>1991</anno>
                <etichetta>Blue Note</etichetta>
            </album>
        </albums>
    </artista>
    <artista>
        <nome>Nick Drake</nome>
        <albums>
            <album>
                <titolo>Pink Moon</titolo>
                <anno>1972</anno>
                <etichetta>Island</etichetta>
            </album>
            <album>
                <titolo>Bryter Layter</titolo>
                <anno>1970</anno>
                <etichetta>Island</etichetta>
            </album>
            <album>
                <titolo>Five leaves left</titolo>
                <anno>1970</anno>
                <etichetta>Island</etichetta>
            </album>
        </albums>
    </artista>
    <artista>
        <nome>Jeff Buckley</nome>
        <albums>
            <album>
                <titolo>Grace</titolo>
                <anno>1994</anno>
                <etichetta>Columbia</etichetta>
            </album>
            <album>
                <titolo>Mistery white boy</titolo>
                <anno>2000</anno>
                <etichetta>Columbia</etichetta>
            </album>
        </albums>
    </artista>
    <artista>
        <nome>Joe Satriani</nome>
        <albums>
            <album>
                <titolo>Surfing with the alien</titolo>
                <anno>1987</anno>
                <etichetta>Epic</etichetta>
            </album>
            <album>
                <titolo>Not of this earth</titolo>
                <anno>1988</anno>
                <etichetta>Relativity</etichetta>
            </album>
        </albums>
    </artista>
</listacd>

and I'm using this XSLT. What I want in output is the value of the tag "titolo".

   <?xml version="1.0" encoding="UTF-8"?>  <!-- Prologo XML -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <!-- Applica questo template al nodo radice 
             indicato dal carattere / -->
        <xsl:template match="/">   
            <html><body>
                <xsl:apply-templates>
                    <!-- Richiama e applica gli altri template -->
                </xsl:apply-templates>
            </body></html>
        </xsl:template>

        <!-- Quando tro

va un nodo artista 
         applica questa regola -->
    <xsl:template match="artista/albums/album">    
        <xsl:value-of select="titolo"></xsl:value-of>
        <br />
    </xsl:template>

</xsl:stylesheet>

Can you explain me why in outupt I've also the value of the tag "nome"? There's no match rules in my template, but this is the output that I receive:

<html>
   <body>    

              Stanley Jordan 

                  Magic Touch<br>
                  Stolen Moments<br>



              Nick Drake

                  Pink Moon<br>
                  Bryter Layter<br>
                  Five leaves left<br>



              Jeff Buckley

                  Grace<br>
                  Mistery white boy<br>



              Joe Satriani

                  Surfing with the alien<br>
                  Not of this earth<br>



   </body>
</html>
Foi útil?

Solução

This is because XSLT has built-in template rules. These are templates that used by XSLT if it can't find a matching template for a node in your XSLT. For elements (and the document node) the built-in template will not output it, but look for templates that match its children. For a text node, it will output the text.

In your XSLT, you start off by doing this

<xsl:apply-templates />

This will cause XSLT to look for templates that match the children of the document node, which is this case is listacd. As you don't have a template matching this, the built-in templates are used. They will continue to be used to match artista and then nome where the text is then output.

One solution, is to replace the <xsl:apply-templates /> with this, to explicitly tell XSLT what elements to look for.

<xsl:apply-templates select=".//album"/>

Alternatively, keep <xsl:apply-templates /> and add a template that matches text() nodes, and ignores then, rather than letting the built-in template process them.

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

For example, try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="artista/albums/album">
        <xsl:value-of select="titolo"/>
        <br/>
    </xsl:template>

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

Bonus points for the choice of music in your XML, by the way!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top