[xsl] how to break down a large XML file in small chunks

Subject: [xsl] how to break down a large XML file in small chunks
From: juan valentín-pastrana <jvalentin@xxxxxxxxxx>
Date: Sat, 31 Jul 2004 20:57:18 +0200
I have a large xml with this structure. input file:
<xml>
  <header>...</header>
  <instances>
    <instance>...</instance>
    <instance>...</instance>
     ...
    <instance>...</instance>
  </instances>
</xml>

and I want to get a set of files limited to maximum number of instances,
each one having the same structure (header included), so I get a set of
smaller files with limited number of instances: output.i.xml (i=1..N):

I wrote this code (for xalan):
<xsl:param name="maxlines" select="512" />
<xsl:variable name="totalines"><xsl:value-of
select="count(/xml/instances/instance)" /></xsl:variable>

<xsl:template match="/">
<xsl:choose>
  <xsl:when test="element-available('redirect:write')">
    <xsl:for-each select="xml/instances/instance">
      <xsl:if test="((position()-1) mod $maxline)=0">
        <xsl:call-template name="block">
          <xsl:with-param name="firstcount"><xsl:value-of
select="position()" /></xsl:with-param>
          <xsl:with-param name="lastcount"><xsl:value-of
select="position()+$maxlines" /></xsl:with-param>
        </xsl:call-template>
      </xsl:if>
    </xsl:for-each>
  </xsl:when>
  <xsl:otherwise>
    <xsl:comment>Xalan extensions not installed</xsl:comment>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="block">
  <xsl:param name="firstcount" />
  <xsl:param name="lastcount" />
  <xsl:variable name="filename" select="concat('output.',
format-number($lastcount div $maxlines, '#'), '.xml')" />
  <xsl:variable name="chunk" select="format-number($lastcount div $maxlines,
'#')" />
  <xsl:variable name="chunks"
select="format-number(count(/xml/instances/instance) div $maxline, '#')+1"
/>
  <redirect:open select="$filename" />
  <redirect:write select="$filename">
  <xsl:comment>chunk number <xsl:value-of select="$chunk" />/<xsl:value-of
select="$chunks" /></xsl:comment>
<xml>
  <xsl:copy-of select="/xml/header" />
  <instances>
    <xsl:for-each select="/xml/instances/instance">
      <xsl:if test="(position() &gt;= $firstcount) and (position() &lt;=
$lastcount)">
        <xsl:copy-of select="." />
      </xsl:if>
    </xsl:for-each>
  </instances>
</xml>
  </redirect:write>
  <redirect:close select="$filename" />
</xsl:template>

any further optimisation ?
code for other precessor extensions ?

thanks

- --
"Se puede resistir el avance de un ejircito, pero no de una idea cuyo momento
ha llegado"
Victor Hugo

Juan Valentmn-Pastrana
jvalentin@xxxxxxxxxx

Current Thread