xsltapply-templates

XSLT multiple stylesheets


I have the following xml

<TopLevel>
  <data m="R263">
    <s ut="263firstrecord" lt="2013-02-16T09:21:40.393" />
    <s ut="263secondrecord" lt="2013-02-16T09:21:40.393" />
  </data>
  <data m="R262">
    <s ut="262firstrecord" lt="2013-02-16T09:21:40.393" />
    <s ut="262secondrecord" lt="2013-02-16T09:21:40.393"  />
  </data>
</TopLevel>

I have some XSLT that does the call template but it's not itterating correctly.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="data">
<xsl:value-of select="@m" />
<xsl:variable name="vYourName" select="@m"/>
    <xsl:choose>
        <xsl:when test="@m='R262'">
            <xsl:call-template name="R262"/>
        </xsl:when>
    </xsl:choose>
    <xsl:choose>
        <xsl:when test="@m='R263'">
            <xsl:call-template name="R263"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

<xsl:template name="R262">
                        <xsl:for-each select="/TopLevel/data/s">
                                        Column1=<xsl:value-of select="@ut" />
                    Column2=<xsl:value-of select="@lt" />
            </xsl:for-each>
</xsl:template>

<xsl:template name="R263">
                        <xsl:for-each select="/TopLevel/data/s">
                                        Column1=<xsl:value-of select="@ut" />
                    Column2=<xsl:value-of select="@lt" />
            </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

This gives me 8 records insead of the 4 (<s> level) records. I know it has to do with my iteration ... but I am not sure how to address this.

I am also aware of the apply stylesheets but I couldn't unravel that mystery either ... If someone can help me with XSLT that will only process everything from <TopLevel> to <\TopLevel> checking the value of m at the <data> level and applying the stylesheet at the <s> level for each <s> record I will be greateful beyond belief.


Solution

  • I don't know what output you want to produce, but I suspect you want to replace

    <xsl:for-each select="/TopLevel/data/s">
    

    by

    <xsl:for-each select="s">
    

    that is, you only want to process the "s" elements within the "data" you are currently processing, rather than selecting all the "s" elements in the whole document.

    Why not do this using apply-templates?

    <xsl:template match="data">
      ...
      <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="s[../@m='R262']">
      ...
    </xsl:template>
    
    <xsl:template match="s[../@m='R263']">
      ...
    </xsl:template>