Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying templates to elements in a variable/sequence

When I use "apply-templates" and select a variable sequence, does the template act upon the context of the element in the sequence, or does it act upon the context of the element in the document?

In the below example, it seems to do either, or none, but I don't understand why.

<root>
<a/>
<b/>
<c><a/></c>
<a/>
</root>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="root">
    <!--this variable give me a sequence of "a" elements-->
    <xsl:variable name="someElementA1" select="//a"/>
    <xsl:variable name="someElementA2">
        <xsl:copy-of select="//a"/>
    </xsl:variable>
    <xsl:for-each select="$someElementA1/a">
        <xsl:element name="test">
            <xsl:text>This is scenario 1: </xsl:text>
            <xsl:apply-templates select="."/>
        </xsl:element>
    </xsl:for-each>
    <xsl:for-each select="$someElementA2/a">
        <xsl:element name="test">
            <xsl:text>This is scenario 2: </xsl:text>
            <xsl:apply-templates select="."/>
        </xsl:element>
    </xsl:for-each>
    <xsl:element name="test">
        <xsl:text>This is scenario 3: </xsl:text>
        <xsl:apply-templates select="$someElementA1"/>
    </xsl:element>
    <xsl:element name="test">
        <xsl:text>This is scenario 4: </xsl:text>
        <xsl:apply-templates select="$someElementA2/a"/>
    </xsl:element>
</xsl:template>
<!--these are the templates to apply--> 
<xsl:template match="a[parent::c]">
    <xsl:text>This element has a parent</xsl:text>
</xsl:template>
<xsl:template match="a[parent::root]">
    <xsl:text>This element is in the root element</xsl:text>
</xsl:template>
<xsl:template match="a">
    <xsl:text>This element is in the sequence</xsl:text>
</xsl:template>
</xsl:stylesheet>

OUTPUT:

<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 3: This element is in the root elementThis element has a parentThis element is in the root element</test>
<test>This is scenario 4: This element is in the sequenceThis element is in the sequenceThis element is in the sequence</test>
like image 744
Darin Walsh Avatar asked Nov 05 '22 11:11

Darin Walsh


1 Answers

The results you get are due to the following facts:

  1. A sequence of nodes contains the nodes as they are in their respective document -- not copies of the nodes.

  2. <xsl:copy-of> creates a copy of each node selected by the expression in the select attribute.

creates a new XML fragment (temporary tree) and this is the value of the variable $someElementA2

$someElementA1/a

does not select any node, because none of the elements in $someElementA1 have any children named a.

$someElementA2/a

selects all elements a that are children of the document node (/).

like image 156
Dimitre Novatchev Avatar answered Nov 11 '22 15:11

Dimitre Novatchev