如何根据参数申请导入XSLT模板

时间:2013-12-16 15:29:10

标签: xml templates xslt xslt-2.0

我希望了解如何根据XML文件中的参数将模板应用于XML文件。

XML文件具有以下格式:

<workfile>  
    <query>  
        <some-info-1/>  
        <some-info-2/>  
        <some-info-3/>  
        <some-info-4/>  
        <some-info-5/>  
        <some-info-6/>  
        <some-info-7/>  
        <parameter name="hours-min" value="7" />  
        <parameter name="hours-max" value="9" />  
        <parameter name="output-type" value="type-1" />  
    </query>  
</workfile>

XML文件由另一个程序生成,并且需要特定的输出格式,具体取决于参数“output-type”的值。如果必须同时为多个输出生成结果,则此参数可能会多次出现,因此需要for-each循环。

编辑以下是一个包​​含多个输出类型参数的示例:

<workfile>  
    <query>  
        <some-info-1/>  
        <some-info-2/>  
        <some-info-3/>  
        <parameter name="hours-min" value="7" />  
        <parameter name="hours-max" value="9" />  
        <parameter name="output-type" value="type-1" />  
        <parameter name="output-type" value="type-2" />  
        <parameter name="output-type" value="type-3" />  
    </query>  
</workfile>

我想创建一个主模板文件generate-main.xsl,并在文件中导入/包含其他模板文件(generate-type-1.xsl,generate-type-2.xsl等等) )。每个模板都必须从根节点(/)开始工作。但我在设想如何做到这一点时遇到了问题。

这是我写的generate-main.xsl基础:
         

<xsl:template match="/">
    <results>
        <xsl:for-each select="/workfile/query/parameter[@name='output-type']">
            <xsl:variable name="outputType" select="./@value" />
            <xsl:choose>
                <xsl:when test="$outputType='type-1'">
                    <xsl:call-template name="type-1" />
                </xsl:when>
                <xsl:when test="$outputType='type-2'">
                    <xsl:call-template name="type-2" />
                </xsl:when>
                <xsl:when test="$outputType='type-3'">
                    <xsl:call-template name="type-3" />
                </xsl:when>
                <xsl:when test="$outputType='type-4'">
                    <xsl:call-template name="type-4" />
                </xsl:when>
                <xsl:when test="$outputType='type-5'">
                    <xsl:call-template name="type-5" />
                </xsl:when>
                <xsl:otherwise>
                </xsl:otherwise>
            </xsl:choose>
            </xsl:for-each>
        </results>
    </xsl:template>

    <xsl:template name="type-1">
        <!-- TO DO -->
    </xsl:template>

    <xsl:template name="type-2">
        <!-- TO DO -->
    </xsl:template>

    <xsl:template name="type-3">
        <!-- TO DO -->
    </xsl:template>

    <xsl:template name="type-4">
        <!-- TO DO -->
    </xsl:template>

    <xsl:template name="type-5">
        <!-- TO DO -->
    </xsl:template>
</xsl:stylesheet>

我确实对此进行了研究。例如,Dimitre Novatchev在模板位于同一个XSL文件(Applying different XSLT template depending on a parameter)时回答了这个问题,但我没有找到如何使用从根节点工作的导入XSL文件。

所以我的问题是:
1)是否可以在主XSL文件中包含或导入模板,并且只能根据参数调用一个模板(例如,通过在被调用模板中播放包含?)
2)如果所有包含的模板都与根节点一起工作(并且我认为是从<template match="/">开始),它仍然可能吗?

非常感谢任何帮助。

Anton Harris

1 个答案:

答案 0 :(得分:2)

在没有源文档的情况下,在编译时包含并导入工作,因此您无法根据在数据中找到的内容导入或包含内容(除非您想进入动态样式表生成,我怀疑在这里是合适的。)

我不清楚为什么使用标准的apply-templates机制无法解决问题。替换这个东西:

<xsl:for-each select="/workfile/query/parameter[@name='output-type']">
            <xsl:variable name="outputType" select="./@value" />
            <xsl:choose>
                <xsl:when test="$outputType='type-1'">
                    <xsl:call-template name="type-1" />
                </xsl:when>

<xsl:template name="type-1">
    <!-- TO DO -->
</xsl:template>

(非常类似于XSLT,并且详细)

<xsl:apply-templates select="/workfile/query/parameter[@name='output-type']"/>

<xsl:template match="parameter[@name='output-type'][@value='type1']">
<!-- TO DO -->
</xsl:template>

为什么您希望所有包含的模板从根节点开始?