在XSLT中解析变量

时间:2017-03-29 09:06:32

标签: xslt xpath

我在解决XSLT中的变量方面遇到了问题。我有一个具有固定值的工作XSL文件,我现在想要使其动态化(一旦它工作,变量声明将移出XSL文件)。我目前的问题是在starts-with函数中使用变量$ begin。这是所有谷歌搜索让我相信它应该看起来的方式,但它不会编译。它的工作方式我在substring-after函数中使用它。该怎么做?

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:variable name="oldRoot" select="'top'" /> 
<xsl:variable name="beginning" select="concat('$.',$oldRoot)" /> 
<xsl:variable name="newRoot" select="'newRoot'" /> 

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

<xsl:template match="bind/@ref[starts-with(., $beginning)]">
    <xsl:attribute name="ref">
        <xsl:text>$.newRoot.</xsl:text><xsl:value-of select="$oldRoot"></xsl:value-of>
        <xsl:value-of select="substring-after(., $beginning)" />
    </xsl:attribute>
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

在XSLT 1.0中,模板匹配表达式包含变量(参见https://www.w3.org/TR/xslt#section-Defining-Template-Rules)会被视为错误,因此该行失败

<xsl:template match="bind/@ref[starts-with(., $beginning)]">

(我相信某些处理器可能允许它,但如果他们遵循规范,他们就不应该。但是在XSLT 2.0中允许它。)

您可以做的是在模板中移动条件,并使用xsl:choose

处理它

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:variable name="oldRoot" select="'top'" /> 
<xsl:variable name="beginning" select="concat('$.',$oldRoot)" /> 
<xsl:variable name="newRoot" select="'newRoot'" /> 

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="bind/@ref">
    <xsl:choose>
        <xsl:when test="starts-with(., $beginning)">
            <xsl:attribute name="ref">
                <xsl:text>$.newRoot.</xsl:text><xsl:value-of select="$oldRoot"></xsl:value-of>
                <xsl:value-of select="substring-after(., $beginning)" />
            </xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="." />
        </xsl:otherwise>            
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>