引用节点集而不复制它

时间:2014-05-28 19:02:29

标签: xml xslt xslt-1.0

在样式表的深处,我有一些看起来像这样的逻辑:

<xsl:variable name="v1">
    <!-- define structure within v1 -->
</variable>
<xsl:variable name="v2">
    <!-- define structure within v2 -->
</variable>
<xsl:variable name="valuesMap" select="exsl:node-set($v1)"/>
<xsl:variable name="valuesMap_2" select="exsl:node-set($v2)"/>
...
<xsl:variable name="tmp">
    <xsl:choose>        
        <xsl:when test="$isSomeCondition">
            <xsl:copy-of select="$valuesMap"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="$valuesMap_2"/>
        </xsl:otherwise>
     </xsl:choose>
 </xsl:variable>
 <xsl:variable name="valueSet" select="exsl:node-set($tmp)"/>
 <xsl:choose>
    <xsl:when test="not($valueSet/Child[@someAttribute=$someOtherVariable])">
       ...
    </xsl:when>
    ...

变量$valuesMap$valuesMap_2是包含节点集的变量。它们在别处定义,并在此转换中引用了几个位置。

我要做的是检查一个条件($isSomeCondition),然后设置一个局部变量$valueSet,以引用$valuesMap$valuesMap_2。我这样做是因为此模板中有几个地方需要在$valuesMap$valuesMap_2之间进行选择,我宁愿做出一次决定并使用局部变量来跟踪它

上面的代码有效,但我担心使用copy-of:我担心它会完全复制$valuesMap$valuesMap_2的内容,这可能是一个问题因为这些变量可以包含一些相当大的结构,每个转换将使用这个特定的模板多次。

我已经尝试过使用value-of,但这似乎捕获了变量的 text 内容,而不是XML结构。

有没有办法引用正确的结构而不必复制它?

2 个答案:

答案 0 :(得分:3)

将两个变量合并为一个,例如

<xsl:variable name="vMapRTF">
  <v1>
    <!-- define structure within v1 -->
  </v1>
  <v2>
    <!-- define structure within v2 -->
  </v2>
</xsl:variable>

<xsl:variable name="vMap" select="exsl:node-set($vMapRTF)" />

<xsl:variable name="valueSet" select="$vMap/*[2 - $isSomeCondition]" />

在这里,我利用了这样一个事实:如果数字上下文中的布尔表达式为假,则将其视为0,如果它为真,则将1视为$isSomeCondition ,如果$vMap/*[1]为真,则选择v1$vMap/*[2]元素),如果错误,则选择$valuesMap

如果你仍然需要单独的$valuesMap_2<xsl:variable name="valuesMap" select="$vMap/v1" /> 变量用于转换中的其他地方,那么只需将它们声明为例如。

{{1}}

答案 1 :(得分:0)

我在"dynamic" package of EXSLT中使用“评估”功能找到了另一种解决方案:

<xsl:variable name="tmpName">
    <xsl:choose>        
        <xsl:when test="$isSomeCondition">
            <xsl:text>$valuesMap</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>$valuesMap_2</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>
<xsl:variable name="valueSet" select="dyn:evaluate($tmpName)"/>
 <xsl:choose>
    <xsl:when test="not($valueSet/Child[@someAttribute=$someOtherVariable])">
       ...
    </xsl:when>
    ...

另一方面,这使用eval函数...我猜Ian仍然表现得比这更好,...我猜这个解决方案可能比使用copy-of的原始问题表现更好。