我正在使用xslt 1.0,我需要两个变量的联合,这意味着我必须使用节点集函数。
下面的测试用例创建单个节点与包含此节点的集合的并集。由于A包含B,因此union操作应该返回B.但是我得到一个带有重复A的新集合。
如果我直接使用xpath,union会按预期运行。如果我使用变量和节点集函数,我将面临意外情况。我的场景要求我使用node-set。我尽可能地简化了测试用例。
这是xml内容:
<?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>
,这是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>
如何在两个node-set()调用上应用union?
答案 0 :(得分:0)
我认为node-set()不是罪魁祸首。
您已使用xsl:copy-of定义了变量t2-events
和specific-t2
。因此,您的变量应该(并且确实)包含由xsl:copy-of上的选择表达式选择的节点的新副本(新元素节点)。因此,两个变量中的event
元素都不与输入中的任何event
元素相同,并且类似地,两个变量中的两个事件2副本是两个副本,不是两个引用单个副本。
请注意,当我们在调试代码中添加一些变量时(顺便说一下这个示例很好!),无论我们是否使用node-set(),联合都会按照我们的预期发生。 (至少在xsltproc中。)
在你最初的两个变量之后,我又增加了两个:
<xsl:variable name="T2-EVENTS"
select="root/event
[eventType = 'TYPE2' and parent = '3']"/>
<xsl:variable name="SPECIFIC-T2"
select="root/event
[eventType = 'TYPE2' and id = '2']"/>
然后在你的DEBUG元素中,我添加了:
<xsl:variable name="dummy3"
select="$T2-EVENTS | $SPECIFIC-T2 "/>
<xsl:variable name="dummy4"
select="ext:node-set($T2-EVENTS)
| ext:node-set($SPECIFIC-T2) "/>
和
<dummy3>
<xsl:comment>How many here?</xsl:comment>
<xsl:copy-of select="$dummy3"/>
</dummy3>
<dummy4>
<xsl:comment>How many here?</xsl:comment>
<xsl:copy-of select="$dummy4"/>
</dummy4>
当我使用xsltproc运行生成的样式表时,dummy3
中有两个元素,dummy4
中有两个元素;对node-set()的调用没有任何区别。
(也就是说,我在the description of the node-set() function on the EXSLT site中看不到任何关于node-set()保留节点标识或不保留节点标识的内容。所以无论如何我都会谨依赖它。)