XML and XSLT apply-templates select

1.1k Views Asked by At

Here's the XML file:

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="2.xsl" ?>


<root>
    <shop>
        <person> 
            <employee> 
                <name> Alexis </name> 
                <role> Manager </role> 
                <task> Sales </task> 
            </employee> 

            <employee>
                <name> Employee2 </name>
            </employee>
        </person>

        <employee>
            <name> Blake2 </name>
        </employee>

    </shop>



    <person> 
        <employee2>
            <role2> Supervisor </role2> 
            <name2> Blake </name2> 
            <task2> Control </task2> 
        </employee2>
    </person>
</root>

Here's the XSLT file:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">



<xsl:template match="root"> 
<html><head></head> 
<body>
Start of root in XSLT <p/> <xsl:apply-templates select="person" /> <p/>

End of root in XSLT

</body> 
</html> 
</xsl:template> 



<xsl:template match="shop">
"Step 1 start"
<xsl:apply-templates select="*/*"/>
"Step 1 done" <p/>
</xsl:template> 



<xsl:template match="employee"> 
<u> <xsl:apply-templates select="name"/> </u> 
(Task: <xsl:apply-templates select="task"/>) 
<br></br> 
</xsl:template> 


</xsl:stylesheet>

The output is:

Start of root in XSLT

Supervisor Blake Control

End of root in XSLT

My question is, why isn't Alexis and Employee2 part of the output? They're both under the <person> element.....

2

There are 2 best solutions below

0
On BEST ANSWER

<xsl:template match="root"> is applied to the <root> element. In there, <xsl:apply-templates select="person" /> selects the <person> element that is an immediate child of the current node (the root element <root>). As there is no template defined for <person> itself, XSLT's default behavior is executed which means that only text nodes are copied.

The other templates are not executed at all, as there are no <shop> or <employee> elements on the root level (relative to the document itself), and the templates are not invoked via <apply-templates>, either.

To answer your question more explicitly, the first <person> element does not get selected because it is nested in another element, but your <apply-templates> instruction only selects <person> elements that are directly visible in the current node.

0
On

But you don't want just any person do you? In case you do but didn't know how to say that, just slash around a bit, like <xsl:apply-templates select="//person" />