Re: [xsl] Can a named template return a node list?

Subject: Re: [xsl] Can a named template return a node list?
From: John <john-xsl-list@xxxxxxxx>
Date: Thu, 16 Jun 2005 14:05:51 -0700
Thanks a lot, that fixed it. But now I have a new question, though not really expecting any response.

I am working in a .NET environment with some existing XSL extensions. One of these is a function that I can invoke with code such as:

<xsl:variable name="whatever" select="custom:function( 'someid', . )" />

I understand that custom:function is basically a method in a .NET class, which does return a pointer/reference to an existing node in the current XML document, and I can reference attributes of that node using $whatever/@attr instead of $whatever/*/@attr. I guess this is because call-template always returns what I would call a string, and .NET can return an XPathNodeIterator (or whatever). I like the shorter syntax (no /*) of the .NET method; another objection is that a programmer using these existing .NET extensions along with my XSL template library would need to know that they sometimes need to add /* to dereference variables.

Dimitre Novatchev wrote:
 <xsl:variable name="somenode" select="msxsl:node-set( $somedata )" />
 <xsl:value-of select="$somenode/@attr" />


You are trying to get the value of an attribute of the document node
of a temporary tree.

A document nodes (root nodes in XSLT 1.0 terminology) doesn't have
attributes as it is not an element node.

Probably you meant:

<xsl:value-of select="$somenode/*/@attr" />


Cheers, Dimitre Novatchev

On 6/17/05, John <john-xsl-list@xxxxxxxx> wrote:

Thanks.  I want to use a named template to avoid putting certain XPath
statements in multiple locations.  Maybe there is a better way.

Since I don't think there is a pure XSL solution I have been trying with
node-set, but that's not working for me either.  This seems to give no
output; I am pretty sure the solution is something obvious but I don't
see it.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:template match="*">
 <xsl:variable name="somedata">
   <xsl:call-template name="sometemplate" />
 </xsl:variable>
 <xsl:variable name="somenode" select="msxsl:node-set( $somedata )" />
 <xsl:value-of select="$somenode/@attr" />
</xsl:template>

<xsl:template name="sometemplate">
 <xsl:copy-of select="/root/node1" />
</xsl:template>

</xsl:stylesheet>

And the sample data again:

<root>
 <node1 attr="node1attrval">
   <node1a>node1atext</node1a>
 </node1>
 <node2 attr="node1attrval">
   <node2a>node2atext</node2a>
 </node2>
</root>

David Carlisle wrote:

<xsl:variable name="somenode">
    ....

xsl:variable with content and no select attribute always (in xslt1)
generates a result tree fragment not a node set. Therefor you can not
query into the variable using XPath (or anything else) You can only copy
it to the result, using copy-of or use it as a string.




and I am hoping to stay away from XSL extensions if possible.


It's hard to avoid xx:node-set() (which is designed exactly to get round
this problem) Most systems have a node-set() extension function (with
mozilla's transformiix engine being the main exception)

Of course if your templates are not actually creating any new nodes (as
in your example) then you have an easy solution: just use xsl:variable
with select as in

<xsl:template match="*">
  <xsl:variable name="somenode"select="/root/node1" />
  <xsl:value-of select="$somenode/@attr" />
</xsl:template>

David

Current Thread