我正在尝试在XML文件上使用XSLT将其转换为另一个XML文件。 这是我的XSLT
<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<xsl:template match="_source/extension">
和另一个匹配
<xsl:template match="/">
但是当我为输入XML运行这个XSLT时,只在我的XML上应用了上面的模板
<xsl:template match="/">
未应用其他匹配(_source / match)。我们可以在同一个XSLT中使用多个模板吗?我可能会在这里遗漏一些东西。
答案 0 :(得分:3)
当然只有match="/"
模板应用于您的XML。它匹配根节点,从不调用任何其他模板,所以没有其他模板被调用的事实不应该是一个惊喜。
要获得更好的结果,请从代码中删除每个<xsl:for-each>
,并将其替换为<xsl:apply-templates>
和相应的匹配模板。 <xsl:for-each>
有其用途,但在您的用例中没有一个出现。
像这样:
<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>
针对做一件事的简短,专注的模板。
使用_source/extension
在正确的位置调用<xsl:apply-templates>
模板。也从该模板中删除<xsl:for-each>
。
阅读What are the differences between 'call-template' and 'apply-templates' in XSL?和For loops vs. apply-templates以及differences between for-each and templates in xsl?以及其他类似文章,了解有关模板在XSLT中如何工作的更多详细信息。