tags:

views:

30

answers:

2

Hello,

I've got some problems with XSL : is it possible to use a template from another one, when it uses an apply-templates to print childs ? I don't want to use current node, but really create a new element matching the template.

Example of what I'm searching :

XML file :

<root>
  <toto name="foo">
    <b>hello</b>
  </toto>
</root>

XSL stylesheet:

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

<xsl:template match="tata" name="tata">
  <div class="tata">
    <xsl:apply-templates />
  </div>
</xsl:template>

<xsl:template match="toto" name="toto">
  <tata>
    <xsl:value-of select="@name" />
  </tata>
  <tata>
    <xsl:apply-templates />
  </tata>
</xsl:template>

<xsl:template match="@*|node()">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
</xsl:template>

Expected output :

<div class="tata">foo</div>
<div class="tata">
  <b>hello</b>
</div>
A: 

If I understand you correctly you are looking for the

<xsl:call-template name="tata" />

element.

Dennis
But how can I pass the content of nodes to tata ? If what I've seen is correct, only wsl:with-param can be used, and I don't see how to use it to pass nodes to xsl:apply-templates of the second template.
Arcanis
+1  A: 

There is no need to call other templates in your problem. You can do practically all the required processing in template match="toto" In fact in your example code, the <xsl:template match="tata"> is never used (with that given input XML). Creating a literal element in a template doesn't result in calling another template matching that element.

This stylesheet

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

    <xsl:output encoding="UTF-8" indent="yes"/>

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

    <xsl:template match="toto">
        <div class="tata">
            <xsl:value-of select="@name"/>
        </div>
        <div class="tata">
            <xsl:apply-templates/>
        </div>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

with this input

<root>
  <toto name="foo">
    <b>hello</b>
  </toto>
</root>

produces the required result

<?xml version="1.0" encoding="UTF-8"?>
<div class="tata">foo</div>
<div class="tata">
<b>hello</b>
</div>

Like Dennis answered, if you want to use a template from another one, use the <xsl:call-template/> element. If you also want to change the current node (context node), you can use

<xsl:apply-templates select="path/to/new/context"/>
jasso
+1 Good answer.
Alejandro
My code is a minimal showcase. In the real one, the "tata" template is not a single classed div, so it's not really beautiful to duplicate a such code for this. And apply-templates seems to be only applicated on XML child nodes, not XSL-created ones (or I don't know how to do).
Arcanis