Hi all,
I have xml files with thousands of sibling nodes, I want to transform the xml so that all this nodes gets grouped in subset of n elements. I have wrote an xsl file for this but it's very slow and I have big files: 20 minutes of cpu time for 20MB file.
Here's an example code.

--input XML--
<?xml version="1.0" encoding="UTF-8"?>
<report>
        <object>1</object>
        <object>2</object>
        <object>3</object>
        <object>4</object>
        <object>5</object>
        ...
        <object>100</object>
</report>

--output XML--
<?xml version="1.0" encoding="UTF-8"?>
<report>
        <object-collection>
                <object>1</object>
                <object>2</object>
                <object>3</object>
                <object>4</object>
                <object>5</object>
        </object-collection>
        <object-collection>
                <object>6</object>
                <object>7</object>
                <object>8</object>
                <object>9</object>
                <object>10</object>
        </object-collection>
        ...
        <object-collection>
                <object>96</object>
                <object>97</object>
                <object>98</object>
                <object>99</object>
                <object>100</object>
        </object-collection>
</report>

-- XSL --
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
               version='1.0'>
<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="/report">
   <report>
       <xsl:for-each select="./object">
           <xsl:if test="position() mod 5 = 1">
               <object-collection>
                   <xsl:apply-templates select="."/>
                   <xsl:variable name="count" select="position()"/>
<xsl:apply-templates select="../object[$count + 1]"/> <xsl:apply-templates select="../object[$count + 2]"/> <xsl:apply-templates select="../object[$count + 3]"/> <xsl:apply-templates select="../object[$count + 4]"/>
               </object-collection>
           </xsl:if>
       </xsl:for-each>
   </report>
</xsl:template>

</xsl:stylesheet>


My solution is the above, but it's not time efficient. Is there a way to do it better?


Reply via email to