如何在XSLT中使用name作为变量调用模板?

时间:2013-09-03 06:12:44

标签: html xslt xslt-1.0

我有以下XML文档需要使用XSLT解析为HTML。

<root>
    <c>
    <c1>
     <id>1</id>
     <text>US</text>
    </c1>
    <c1>
     <id>2</id>
     <text>UK</text>
    </c1>
    </c>
</root>

下面给出了将其转换为HTML的XSLT。

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes" />
    <xsl:template match="root">
        <html>        
                <xsl:for-each select="c/c1">     
                                **<xsl:variable name="vTemplate" select="text"/>                                  
                                <xsl:apply-templates select="$vTemplate[@name='text'"/>**
                </xsl:for-each>
        </html>
    </xsl:template>
    <xsl:template match="xsl:template[@name='text']" name="text">
        <select>
            <xsl:attribute name="id">
                <xsl:value-of select="id"/>
            </xsl:attribute>
        </select>
    </xsl:template>

</xsl:stylesheet>

我需要调用模板取决于文本字段。因此,对于值 US ,将执行一个模板,对于 UK ,将执行另一个模板。 如何在调用模板时使用变量作为模板名称来实现此目的?我刚试了一下,但它给出了错误。有人能帮我弄明白我错在哪里吗?

1 个答案:

答案 0 :(得分:2)

我认为不可能选择动态调用的模板名称。可以做的是xsl:choose利用率(可能与mode属性相结合),像这样

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

    <xsl:template match="/root">
        <html>
            <xsl:for-each select="c/c1">
                <xsl:choose>
                    <xsl:when test="text = 'US'">
                        <xsl:apply-templates select="text" mode="US"/>
                    </xsl:when>
                    <xsl:when test="text = 'UK'">
                        <xsl:apply-templates select="text" mode="UK"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:comment>Something's wrong</xsl:comment>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </html>
    </xsl:template>

    <xsl:template match="text" mode="US">
        <xsl:comment>US mode</xsl:comment>
        <select>
            <xsl:attribute name="id">
                <xsl:value-of select="preceding-sibling::id"/>
            </xsl:attribute>
        </select>
    </xsl:template>

    <xsl:template match="text" mode="UK">
        <xsl:comment>UK mode</xsl:comment>
        <select>
            <xsl:attribute name="id">
                <xsl:value-of select="preceding-sibling::id"/>
            </xsl:attribute>
        </select>
    </xsl:template>

</xsl:stylesheet>

或者您可以将match与适当的谓词一起使用,并避免for-each这样的

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

    <xsl:template match="/root">
        <html>
            <xsl:apply-templates select="//c1" />
        </html>
    </xsl:template>

    <xsl:template match="c1[text = 'US']">
        <xsl:comment>US mode</xsl:comment>
        <select id="{id}" />
    </xsl:template>

    <xsl:template match="c1[text = 'UK']">
        <xsl:comment>UK mode</xsl:comment>
        <select id="{id}" />
    </xsl:template>

</xsl:stylesheet>

id的{​​{1}}属性也可以填充“Attribute value templates”(大括号中的xpath),如上一个示例所示。