如何在变量中存储选择路径?

时间:2014-09-16 21:32:28

标签: xslt

我有一个简单的XML文件:

<employees>
    <employee name="Alice" salary="40000" bonus="1000" />
    <employee name="Bob" salary="50000" bonus="2000" />
    <employee name="Clarisse" salary="60000" bonus="3000" />
    <employee name="David" salary="70000" bonus="4000" />
</employees>

我有一个XSLT文件,只需稍微重新排列数据并提供工资总和:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

    <xsl:template match="employees">
        <root>
            <xsl:apply-templates select="employee" />
            <sum>
                <name>Total</name>
                <salary>
                    <xsl:value-of select="sum(employee/@salary)"/>
                </salary>
            </sum>
        </root>        
    </xsl:template>

    <xsl:template match="employee">
        <item>
            <name><xsl:value-of select="@name"/></name>
            <salary><xsl:value-of select="@salary"/></salary>
        </item>
    </xsl:template>

</xsl:stylesheet>

我的问题涉及薪资数据。假设将来我想用奖金信息替换薪资信息。为此,我必须进行两次修改:我必须将sum(employee/@salary)替换为sum(employee/@bonus),将<xsl:value-of select="@salary"/>替换为<xsl:value-of select="@bonus"/>。 (我现在忽略了<salary>的节点名称。)

有没有办法使用xsl:variable或xsl:key或其他东西来存储上面的@salary部分,这样我只需要进行一次编辑而不是两次?

1 个答案:

答案 0 :(得分:1)

<xsl:stylesheet
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    exclude-result-prefixes="msxsl"
>
    <xsl:param name="sumAttr" select="'salary'" />

    <xsl:template match="employees">
        <root>
            <xsl:apply-templates select="employee" />
            <sum>
                <name>Total</name>
                <xsl:element name="{$sumAttr}">
                    <xsl:value-of select="sum(employee/@*[name() = $sumAttr])"/>
                </xsl:element>
            </sum>
        </root>        
    </xsl:template>

    <xsl:template match="employee">
        <item>
            <name><xsl:value-of select="@name"/></name>
            <xsl:element name="{$sumAttr}">
                <xsl:value-of select="@*[name() = $sumAttr]"/>
            </xsl:element>
        </item>
    </xsl:template>

</xsl:stylesheet>

<xsl:param>默认为'salary',但您可以通过编程方式进行设置。

XSLT 1.0无法在运行时将字符串计算为XPath。换句话说,传入XPath表达式将不起作用。您演示的简单问题可以解决,如上所示。

更复杂的场景也是可以想到的 - 例如使用模板模式,不同的XSL导入甚至是基于脚本的复杂解决方案(因为您引用了msxsl命名空间)。