I'm using xslt 1.0, and I need a union of two variables which means I have to use node-set function.
The test case below creates a union of a single node with a set that contains this node. Since A contains B, the union operation should return B. But I get a new set with duplicate A's.
If I use xpath directly, union behaves as expected. If I use variables and node-set function, I face the unexpected case. My scenario requires that I use node-set. I've simplified the test case as much as I can.
This is the xml content:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<event>
<id>3</id>
<eventType>TYPE1</eventType>
</event>
<event>
<id>2</id>
<eventType>TYPE2</eventType>
<parent>3</parent>
</event>
<event>
<id>1</id>
<eventType>TYPE2</eventType>
<parent>3</parent>
</event>
</root>
and this is the xslt:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="t2-events">
<xsl:copy-of
select="root/event
[eventType = 'TYPE2' and parent = '3']"/>
</xsl:variable>
<xsl:variable name="specific-t2">
<xsl:copy-of
select="root/event
[eventType = 'TYPE2' and id = '2']"/>
</xsl:variable>
<DEBUG>
<results>
<xsl:variable name="dummy"
select="root/event
[eventType = 'TYPE2']
|
root/event[id = '2']"/>
<xsl:variable name="dummy2"
select="ext:node-set($t2-events)
| ext:node-set($specific-t2) "/>
<xsl:comment>Works as expected</xsl:comment>
<dummy>
<xsl:copy-of select="$dummy"/>
</dummy>
<dummy2>
<xsl:comment>There are 3 elements here, where we should have 2</xsl:comment>
<xsl:copy-of select="$dummy2"/>
</dummy2>
</results>
</DEBUG>
</xsl:template>
</xsl:stylesheet>
How do I apply a union on two node-set() calls?
I don't think node-set() is the culprit here.
You've defined your variables
t2-events
andspecific-t2
using xsl:copy-of. So your variables should (and do) contain fresh copies (new element nodes) of the nodes selected by the select expressions on xsl:copy-of. It follows that none of theevent
elements in the two variables is identical with any of theevent
elements in the input, and similarly that the two copies of event 2 made in the two variables are two copies, not two references to a single copy.Note that when we add a few more variables to your debugging code (nice job cutting the example down, by the way!), the union happens as we might expect, regardless of whether we use node-set() or not. (At least in xsltproc.)
After your initial two variables, I added two more:
Then within your DEBUG element, I added:
and
When I run the resulting stylesheet with xsltproc, I get two elements in
dummy3
and two indummy4
; the call to node-set() made no difference.(That said, I cannot see anything in the description of the node-set() function on the EXSLT site that says anything about node-set() preserving node identity or not preserving it. So I would be leery of relying on it either way.)