首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在同一XSLT中使用不同匹配的多个模板

如何在同一XSLT中使用不同匹配的多个模板
EN

Stack Overflow用户
提问于 2016-08-23 02:30:43
回答 1查看 1.5K关注 0票数 1

我正在尝试使用XML文件上的XSLT将其转换为另一个XML文件。这是我的XSLT

代码语言:javascript
复制
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:og="http://og.com"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    exclude-result-prefixes="xs fn">
    <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no"
        indent="yes" />

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

<xsl:template match="_source/extension">
    <xsl:for-each select="*">
        <xsl:element name="MT">
            <xsl:attribute name="N" select="name()"/>
            <xsl:attribute name="V" select="."/>
        </xsl:element>
    </xsl:for-each>
</xsl:template>

    <xsl:template match="/">
        <GSP>
            <xsl:attribute name="VER">
                <xsl:value-of select="3.2" />
            </xsl:attribute>
            <xsl:for-each select="root">
                <TM>
                    <xsl:value-of select="(floor(took) div floor(1000))" />
                </TM>

                <RES>
                    <M>
                        <xsl:value-of select="floor(hits/total)" />
                    </M>
                    <xsl:for-each select="hits/hits">
                        <xsl:variable name="var1_resultof_first" as="node()"
                            select="_source" />
                        <R>
                            <xsl:attribute name="N">
                            <xsl:number format="0" level="single" />
                            </xsl:attribute>
                            <U>
                                <xsl:sequence
                                    select="xs:string(xs:anyURI(fn:string($var1_resultof_first/U)))" />
                            </U>
                            <UE>
                                <xsl:sequence
                                    select="xs:string(xs:anyURI(fn:string($var1_resultof_first/UE)))" />
                            </UE>
                            <UD>
                                <xsl:sequence
                                    select="xs:string(xs:anyURI(fn:string($var1_resultof_first/UD)))" />
                            </UD>
                            <T>
                                <xsl:sequence select="fn:string($var1_resultof_first/T)" />
                            </T>
                            <Last-Modified>
                                <xsl:value-of select="substring-before(_source/submitTime,'T')" /> 
                            </Last-Modified>
                            <S>
                                <xsl:for-each select="highlight/newContent">
                                    <xsl:sequence select="fn:string(.)" />
                                </xsl:for-each>
                            </S>

                        </R>
                    </xsl:for-each>
                </RES>
            </xsl:for-each>
        </GSP>
    </xsl:template>
</xsl:stylesheet>

它有两个匹配到的template.One

代码语言:javascript
复制
<xsl:template match="_source/extension">

和另一个匹配

代码语言:javascript
复制
<xsl:template match="/">

但是,当我对我的输入XML运行这个XSLT时,只有上面的模板被附加到我的XML上

代码语言:javascript
复制
 <xsl:template match="/">

不应用另一个匹配项(_source/match)。我们可以在同一个XSLT中使用多个模板吗?我可能漏掉了什么。

EN

回答 1

Stack Overflow用户

发布于 2016-08-23 02:55:35

当然,只有match="/"模板应用于您的XML。它匹配根节点,并且从不调用任何其他模板,因此没有调用任何其他模板的事实应该不会让人感到惊讶。

为了获得更好的结果,请删除代码中的每个<xsl:for-each>,并将其替换为<xsl:apply-templates>和适当的匹配模板。<xsl:for-each>有其用法,但在您的用例中没有一种用法。

如下所示:

代码语言:javascript
复制
<xsl:template match="/">
    <GSP VER="3.2">
        <xsl:apply-templates match="root" />
    </GSP>
<xsl:template>

<xsl:template match="root">
    <TM>
        <!-- floor(1000) is... 1000. Maybe you mean something else? -->
        <xsl:value-of select="floor(took) div floor(1000)" />
    </TM>
    <RES>
        <M><xsl:value-of select="floor(hits/total)" /></M>
        <xsl:apply-templates="hits/hits" />
    </RES>
</xsl:template>

<xsl:template match="hits/hits">
    <R>
        <xsl:attribute name="N">
            <xsl:number format="0" level="single" />
        </xsl:attribute>
        <!-- you could use select="_source/U,_source/UE,_source/UT" here, too -->
        <xsl:apply-templates select="_source/U" mode="URI" />
        <xsl:apply-templates select="_source/UE" mode="URI" />
        <xsl:apply-templates select="_source/UD" mode="URI" />
        <T><xsl:value-of select="_source/T" /></T>
        <Last-Modified>
            <xsl:value-of select="substring-before(_source/submitTime,'T')" /> 
        </Last-Modified>
        <xsl:apply-templates select="highlight/newContent" />
    </R>
</xsl:template>

<xsl:template match="*" mode="URI">
    <xsl:copy>
        <xsl:value-of select="xs:anyURI(.)" />
    </xsl:copy>
</xsl:template>

<xsl:template match="highlight/newContent">
    <S><xsl:value-of select="." /></S>
</xsl:template>

目标是做一件事的简短的、有重点的模板。

使用<xsl:apply-templates>在正确的位置调用您的_source/extension模板。也从该模板中删除<xsl:for-each>

有关模板如何在What are the differences between 'call-template' and 'apply-templates' in XSL?中工作的更多详细信息,请阅读For loops vs. apply-templatesdifferences between for-each and templates in xsl?以及其他类似的文章。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39086391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档