Reputation: 1498
I am trying to use an XSLT on XML file to convert it into another XML file. This is my 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>
It has two template.One which matches to
<xsl:template match="_source/extension">
and the other which matches to
<xsl:template match="/">
But when I run this XSLT for my input XML, only the above template is being appied on my XML
<xsl:template match="/">
The other match(_source/match) is not applied. Can we use multiple template in the same XSLT? I might be missing something here.
Upvotes: 1
Views: 1791
Reputation: 338336
Of course only the match="/"
template is applied to your XML. It matches the root node and never calls any other template, so the fact that no other template is ever called should not come as a surprise.
For better results, drop every <xsl:for-each>
from your code and replace it with <xsl:apply-templates>
and the appropriate, matching templates. <xsl:for-each>
has its uses, but none of them occur in your use case.
Like this:
<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>
Aim for short, focused templates that do one thing.
Call your _source/extension
template in there at the right place using <xsl:apply-templates>
. Remove the <xsl:for-each>
from that template, too.
Read What are the differences between 'call-template' and 'apply-templates' in XSL? and For loops vs. apply-templates and differences between for-each and templates in xsl?, among other similar posts, for further detail about how templates work in XSLT.
Upvotes: 3