Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old November 11th, 2008, 06:10 AM
Registered User
 
Join Date: Nov 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default Apply-templates combined with with-param ?

Hi!

I'm trying to use a template with a param, but it doesn't seem to work when using apply-templates. Earlier I'm only used call-template with-params, but now that won't do.

<xsl:apply-templates>
                            <xsl:with-param name="someparam">somevalue</xsl:with-param>
 </xsl:apply-templates>

 <xsl:template match="//node">
     <xsl:param name="someparam"/>
          <xsl:value-of select="$someparam"/>
    </xsl:template>


This won't work. Why? How could I make it working?

 
Old November 11th, 2008, 06:28 AM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 291
Thanks: 9
Thanked 29 Times in 29 Posts
Default

It works. Just show the input xml and some more xsl.

------
Rummy
 
Old November 11th, 2008, 06:29 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

The most likely explanation is that your apply-templates call isn't invoking the template rule directly, but indirectly via a built-in template for some intermediate element. The built-in templates in XSLT 1.0 don't pass the parameters on (this has changed in XSLT 2.0). The solution is to supply an explicit template rule for the intermediate element nodes.


Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old November 11th, 2008, 06:40 AM
Registered User
 
Join Date: Nov 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by mrame
 It works. Just show the input xml and some more xsl.

------
Rummy
Are you using XSLT 2.0?

Well, in terms of this problem the structure is as simple as this:

Code:
 
<xsl:template match="/">
     <someNode>
         <xsl:apply-templates>
                <xsl:with-param name="someparam">somevalue</xsl:with-param>
          </xsl:apply-templates>
    </someNode>
 </xsl:template>

 <xsl:template match="//node">
     <xsl:param name="someparam"/>
     <row>    
           Param <xsl:value-of select="$someparam"/>
    </row>
</xsl:template>

 
Old November 11th, 2008, 06:45 AM
Registered User
 
Join Date: Nov 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by mhkay
 The most likely explanation is that your apply-templates call isn't invoking the template rule directly, but indirectly via a built-in template for some intermediate element. The built-in templates in XSLT 1.0 don't pass the parameters on (this has changed in XSLT 2.0).
Hmm... A built-in element? So in what kind of a context would the call happen directly without losing the passed parameter? Why doesn't XSLT 1.0 pass the parameter by default? Isn't it always needed?

Quote:
quote:The solution is to supply an explicit template rule for the intermediate element nodes.
So how is this done in practice?

 
Old November 11th, 2008, 07:01 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

You haven't shown your XML. If it's like this:

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

and your template rules are

<xsl:template match="a">
  <xsl:apply-templates>
    <xsl:with-param name="x">23</xsl:with-param>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="c">
  <xsl:param name="x".../>
</xsl:template>

then the apply-templates call selects the b element, there is no template rule for the b element, so the built-in template rule is invoked, this applies-templates to the c element, but without passing the parameters on. The solution is to add a template rule

<xsl:template match="b">
  <xsl:param name="x"/>
  <xsl:apply-templates>
    <xsl:with-param name="x" select="$x"/>
  </xsl:apply-templates>
</xsl:template>

or to make the call direct:

<xsl:template match="a">
  <xsl:apply-templates select="b/c">
    <xsl:with-param name="x">23</xsl:with-param>
  </xsl:apply-templates>
</xsl:template>

>Why doesn't XSLT 1.0 pass the parameter by default?

Probably an oversight by the language designers. W3C did things a lot more quickly in those days and there wasn't so much time for review. XSLT 2.0 fixes many such usability problems.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old November 11th, 2008, 08:25 AM
Registered User
 
Join Date: Nov 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by mhkay
 You haven't shown your XML.

Ah, sorry. I somehow didn't notice that mrame asked for also that (not only xsl).


Quote:
quote:If it's like this:

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

and your template rules are

<xsl:template match="a">
  <xsl:apply-templates>
    <xsl:with-param name="x">23</xsl:with-param>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="c">
  <xsl:param name="x".../>
</xsl:template>

then the apply-templates call selects the b element, there is no template rule for the b element, so the built-in template rule is invoked, this applies-templates to the c element, but without passing the parameters on. The solution is to add a template rule

<xsl:template match="b">
  <xsl:param name="x"/>
  <xsl:apply-templates>
    <xsl:with-param name="x" select="$x"/>
  </xsl:apply-templates>
</xsl:template>

or to make the call direct:

<xsl:template match="a">
  <xsl:apply-templates select="b/c">
    <xsl:with-param name="x">23</xsl:with-param>
  </xsl:apply-templates>
</xsl:template>
Thanks! That was a very clear explanation to the reason behind the problem. And now it works, when I use the direct call! :)

Quote:
quote:
>Why doesn't XSLT 1.0 pass the parameter by default?

Probably an oversight by the language designers. W3C did things a lot more quickly in those days and there wasn't so much time for review. XSLT 2.0 fixes many such usability problems.
Okay. It's more understandable now that I learned from your example that it practically makes these intermediary template-calls when there are no direct matches.






Similar Threads
Thread Thread Starter Forum Replies Last Post
Exclude Elements in Apply Templates mail4kaja XSLT 18 November 29th, 2008 12:09 PM
xsl:param and xsl:apply-templates' "select" newbieboobers XSLT 1 March 25th, 2008 07:23 PM
apply-templates problem within for-each loop mister_mister XSLT 2 January 22nd, 2007 05:40 PM
Templates Won't Apply neilac333 XSLT 5 October 26th, 2006 01:39 PM
xsl:apply-templates on Variable containing xml nexus5 XSLT 9 November 4th, 2004 02:55 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.