You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在带条件逻辑的xsl:variable中保留元素属性?

XSLT中带条件逻辑的节点变量赋值问题

原始数据

<mydoc>
    <setting>foo</setting>
    <foo sound="aaaa"/>
    <bar sound="brrr"/>
    <cat sound="meow"/>
</mydoc>

无条件逻辑的场景

直接通过select属性指定节点路径,就能获取带属性的完整元素节点,后续可直接访问其属性或子节点:

<xsl:variable name="result1" select="/mydoc/foo"/>

比如可以用$result1/@sound获取该元素的sound属性值。

带条件逻辑的需求

当需要根据setting的值动态选择节点时,原写法的变量无法像result1一样直接作为节点使用:

<xsl:variable name="result2">
    <xsl:choose>
        <xsl:when test="/mydoc/setting='foo'">
            <!-- 此处应编写什么代码 -->
        </xsl:when>
        <xsl:when test="/mydoc/setting='cat'">
            <!-- 此处应编写什么代码 -->
        </xsl:when>
        <xsl:otherwise>
            <!-- 此处应编写什么代码 -->
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

期望效果:

  • 当setting = 'foo'时,result2指向<foo sound="aaaa"/>
  • 当setting = 'cat'时,result2指向<cat sound="meow"/>
  • 其他情况,result2指向<bar sound="brrr"/>

解决方案

方案1:XSLT 2.0+ 版本

使用<xsl:sequence>直接引用原文档中的节点,变量会存储原始元素节点而非生成新节点:

<xsl:variable name="result2" as="element()">
    <xsl:choose>
        <xsl:when test="/mydoc/setting='foo'">
            <xsl:sequence select="/mydoc/foo"/>
        </xsl:when>
        <xsl:when test="/mydoc/setting='cat'">
            <xsl:sequence select="/mydoc/cat"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:sequence select="/mydoc/bar"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

通过as="element()"指定变量类型为元素节点,之后即可像result1一样使用,比如$result2/@sound。

方案2:XSLT 1.0 版本

XSLT1.0不支持<xsl:sequence>,可通过节点集的条件筛选实现:

<xsl:variable name="settingVal" select="/mydoc/setting/text()"/>
<xsl:variable name="result2" select="/mydoc/foo[$settingVal='foo'] | /mydoc/cat[$settingVal='cat'] | /mydoc/bar[not($settingVal='foo' or $settingVal='cat')]"/>

通过管道符|组合不同条件的节点筛选结果,变量result2直接指向符合条件的原始节点,可直接访问其属性。

若一定要用<xsl:choose>结构,需借助EXSLT的node-set()函数将结果树片段转换为节点集(需处理器支持EXSLT扩展):

<!-- 需在XSLT开头声明命名空间:xmlns:exsl="http://exslt.org/common" -->
<xsl:variable name="result2Temp">
    <xsl:choose>
        <xsl:when test="/mydoc/setting='foo'">
            <xsl:copy-of select="/mydoc/foo"/>
        </xsl:when>
        <xsl:when test="/mydoc/setting='cat'">
            <xsl:copy-of select="/mydoc/cat"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="/mydoc/bar"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>
<xsl:variable name="result2" select="exsl:node-set($result2Temp)/*"/>

内容的提问来源于stack exchange,提问作者toddmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:25:25