【问题标题】:How to call template with name as a variable in XSLT?如何在 XSLT 中调用名称为变量的模板?
【发布时间】:2013-09-03 06:12:43
【问题描述】:

我有以下 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,将执行另一个模板。 如何在调用模板时使用变量作为模板名称来实现这一点?我刚试了一下,但它给出了错误。谁能帮我弄清楚我哪里做错了?

【问题讨论】:

    标签: html xslt xslt-1.0


    【解决方案1】:

    我认为不可能选择动态调用的模板名称。可以做的是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>
    

    selectid 属性也可以用“Attribute value templates”(大括号中的xpath)填充,如前面的示例所示。

    【讨论】:

    • 这个答案在主要问题上是正确的(不,调用模板的名称属性中不允许变量引用),但在它开始的附带问题上不太正确。没有理由不使用同一个模板作为命名模板和匹配模板;有时它很有帮助。
    • 感谢您的评论!虽然我知道将一个模板同时作为命名模板和匹配模板是有效的,但我在实践中还没有遇到过。您能否提及(甚至简短地)这种情况?非常感谢您的评论,它只会满足我的好奇心。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    相关资源
    最近更新 更多