【问题标题】:Union of two node-set results leads to duplicated set member两个节点集结果的联合导致重复的集合成员
【发布时间】:2013-08-15 15:26:58
【问题描述】:

我使用的是 xslt 1.0,我需要两个变量的并集,这意味着我必须使用节点集函数。

下面的测试用例创建了单个节点与包含该节点的集合的联合。由于 A 包含 B,联合操作应该返回 B。但是我得到了一个带有重复 A 的新集合。

如果我直接使用 xpath,union 会按预期运行。如果我使用变量和节点集函数,我会遇到意想不到的情况。我的场景要求我使用节点集。我已经尽可能地简化了测试用例。

这是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() 调用应用联合?

【问题讨论】:

    标签: xslt xslt-1.0 node-set


    【解决方案1】:

    我不认为 node-set() 是这里的罪魁祸首。

    您已经使用 xsl:copy-of 定义了变量 t2-eventsspecific-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() 保留节点身份或不保留节点身份的内容。所以无论哪种方式我都会对依赖它持谨慎态度。)

    【讨论】:

    • 谢谢。我认为这是我遇到的问题:我的原始代码也使用 xsl:copy-of。我将处理我的代码,看看我是否可以摆脱副本。
    猜你喜欢
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多