Re: [xsl] creating a node-set at run-time

Subject: Re: [xsl] creating a node-set at run-time
From: David N Bertoni/Cambridge/IBM <david_n_bertoni@xxxxxxxxxx>
Date: Tue, 4 Feb 2003 23:00:11 -0800



> Hi everyone,
>
> We have this xml as our input document:
>
> <list>
>     <item ref="item1.xml"/>
>     <item ref="item2.xml"/>
>     <item ref="item3.xml"/>
>     <item ref="item4.xml"/>
> </list>
>
> We want to go through each of the item elements and using
> the document function, load each item?.xml file and check
> a specific attribute in the root node of that loaded document
> to see if it matches a certain value. If it does match we want
> to add the value of the ref attribute to a node-set.  We want
> to have a variable to which this node-set is assigned, so we
> can do some processing on it at a later time (we want to run
> a diff on it against another node-set amongst other things).

The document() function will parse multiple documents if you call it
correctly.  Read the second paragraph for the details:

   http://www.w3.org/TR/xslt#document

So:

   <xsl:variable name="nodes" select="document(/list/item/@ref)"/>

will create a node-set variable containing the root nodes of the documents.
You can search within the node-set like this:

   select="$nodes/*/@attr[. = 'foo']"

There's also no reason why you can't just select these nodes all at once:

   <xsl:variable name="nodes" select="document(/list/item/@ref)/*/@attr[. =
   'foo']"/>

which would select all of the attribute nodes of all the document elements
with the name 'attr' that have the value 'foo'.

I don't know what you mean by this:

   "If it does match we want to add the value of the ref attribute to a
   node-set"

If "value" means the string value of an attribute, you cannot add that to a
node-set, unless you mean arithmetic addition, and then, I'm still not sure
what you're trying to accomplish.

> Basically this is like storing items into a variable (eg
> var = var + new_item), but as we know, you can't reassign values
> to a variable.
>
> So can this be done using XSLT?  I was trying to come up with a
> recursive algorithm to do this, but am not sure how.

Since a template can only create a result tree fragment, you can't create a
node-set with a recursive algorithm in XSLT 1.0.  You could create a result
tree fragment, then convert it to a node-set using a processor-specific
extension, but I don't think you need to do that.

> We want  to have a variable to which this node-set is assigned,
> so we can do some processing on it at a later time (we want to
> run a diff on it against another node-set amongst other things).

"diffing" two node-sets is not as easy as you might think, since neither
XPath nor XSLT has a node identity test (aside from generate-id() hacks).
Some processors have node-set extensions that implement set operations
suchs as difference, intersection, etc., which you can use to do this sort
of thing, but the equality operator will _not_ work.

Hope that helps...

Dave


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread