Subject: RE: [xsl] 'apply-templates' on parameter of 'call-template' From: "M. David Peterson" <m.david@xxxxxxxxxx> Date: Fri, 9 Apr 2004 11:53:51 -0600 |
No, this will definitely will not work. But its not because the actual code itself is not valid but instead the data that is being sent with the "body" with-param is considered to be a string to the processor even though to you and I it looks just like valid XML. The function of xsl:apply-templates is not to match the value of an element but instead, the element name itself. Actually, you could use the value of an element or attribute to match an element to the proper template but the syntax requires to first match the element or attribute name accompanied by the desired value following the "=" sign (e.g. match="matchable[@id = '123'] is valid match="123" is not. In your particular case you're the param that you are passing ("body") is being interpreted by the processor as a string as opposed to a node-set or Result Tree Fragment and as such you are technically trying to match a string with the value of "<p>This is my body</p><matchable id="123"/>" to a template. As you pointed out various processors handled this differently as there are no rules as to how a processor HAS TO handle errors in your XSLT. Frustrating, I know... but theres not a whole lot that can be done about that. There are a handful of XSLT validators out there that do a good job of parsing your XSLT and validating it, throwing human understandable reasons as to why something will not work. If necessary post another message to the list asking advice on a good human understandable XSLT validator and im sure you'll get more than a handful of good responses. In the mean time here are several ways to fix this. The first would be to pass a valid Result Tree Fragment to the template using valid XPath in the select statement attribute of xsl:with-param. The second would be to use the node-set function specific to your processor. This was not part of the original specification for XSLT 1.0 although it should have been. As such all major XSLT processors have some sort of variation of the node-set function. You will need to declare the correct namespace specific to the processor you are using and then use a combination of that namespace and the proper node-set function name for that namespace e.g. xalan:nodeset($body) or msxsl:node-set($body). The easiest way to implement this second format would be to create a variable with the desired xml as its value(at this point its actually still a string to the eyes of the processor but to you it would look like valid xml.) If the name of the variable you created was "body" then you would use: <xsl:with-param name="body" select="xalan:nodeset($body)"/> or the namespace and proper node-set name for the processor you want to use. Note: using the same name for the variable and with-param tends to be the easiest as far as managing your code is concerned. However, its definitely not mandatory. I hope this helps! Best regards, <M:D/> -----Original Message----- From: Angus McIntyre [mailto:angus@xxxxxxxxx] Sent: Friday, April 09, 2004 11:08 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: [xsl] 'apply-templates' on parameter of 'call-template' Is it legitimate to invoke 'xsl:apply-templates' on a parameter passed to 'xsl:call-template'? In other words, should the following fragment be expected to work: <xsl:template match="/"> <xsl:call-template name="test"> <xsl:with-param name="body"> <p>This is my body</p> <matchable id="123"/> </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template name="test"> <xsl:param name="body">no body</xsl:param> <xsl:apply-templates select="$body"/> </xsl:template> <xsl:template name="matchable"> <p>The value is <xsl:value-of select="@id"/></p> </xsl:template> On the test platform I'm using (TestXSLT from Marc Liyanage), the different stylesheet processors all choke on this in different ways. Xalan throws an error, LibXSLT ignores it, Saxon and Sablotron blow up. Replacing the 'xsl:apply-templates' in the named template 'test' by 'xsl:copy-of' works fine - except that, of course, the "matchable" template is never invoked. The Xalan error ("can not convert #RTREEFRAG to a nodelist") hints that I'm trying to do something basically contrary to the spirit of XSL, or at least XSL 1.0. What I'd like to do can be described as follows: use 'call-template' to 'surround' an arbitrary block of XML, _contained in the XSL stylesheet_, by additional XML content - and have templates applied to the contained block in the usual way. As to why I want to do this particularly horrible thing, put it down to someone else's questionable design decisions. If the nodes that I want to 'surround' were in the XML rather than the XSL, this would be trivial. Thanks in advance for any suggestions, Angus -- Business: http://www.nomadcode.com/ Personal: http://www.raingod.com/angus/ Political: http://www.gollum2004.com/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] 'apply-templates' on paramete, Angus McIntyre | Thread | Re: [xsl] 'apply-templates' on para, G. Ken Holman |
[xsl] 'apply-templates' on paramete, Angus McIntyre | Date | Re: [xsl] 'apply-templates' on para, G. Ken Holman |
Month |