Improving the performance of XSL
        Posted  
        
            by Rachel
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Rachel
        
        
        
        Published on 2010-06-01T16:58:15Z
        Indexed on 
            2010/06/01
            17:03 UTC
        
        
        Read the original article
        Hit count: 524
        
In the below XSL for the variable "insert-data", I have an input param with the structure,
 <insert-data>
 <data compareIndex="4" nodeName="d1e1">
    <a/>
 </data>
 <data compareIndex="5" nodeName="d1e1">
    <b/>
 </data>
 <data compareIndex="7" nodeName="d1e2">
         <a/>
      </data>
 <data compareIndex="9" nodeName="d1e2">
         <b/>
 </data>
 </insert-data>
where "nodeName" is the id of a node and "compareIndex" is the position of the text content relative to the node having id "$nodeName".
I am using the below XSL to select all the text nodes(generate-id) that satisfy the above condition and construct a data xml. The below implementation works perfectly but the time taken for the execution is in min. Is there a better way of implementing or is there any in-efficient operation being used. From my observation the code where the preceding text length is calculated consumes the major time. Please share your thoughts to improve the performance of the XSL. I am using Java SAXON XSL transformer.
   <xsl:variable name="insert-data" as="element()*"> 
   <xsl:for-each select="$insert-file/insert-data/data">
   <xsl:sort select="xsd:integer(@index)"/>
        <xsl:variable name="compareIndex" select="xsd:integer(@compareIndex)" />
        <xsl:variable name="nodeName" select="@nodeName" />
        <xsl:variable name="nodeContent" as="node()">
            <xsl:copy-of select="node()"/> 
        </xsl:variable>
            <xsl:for-each select="$main-root/*//text()[ancestor::*[@id = $nodeName]]">
                <xsl:variable name="preTextLength" as="xsd:integer" select="sum((preceding::text())[. ancestor::*[@id = $nodeName]]/string-length(.))" />
                <xsl:variable name="currentTextLength" as="xsd:integer" select="string-length(.)" />
                <xsl:variable name="sum" select="$preTextLength + $currentTextLength" as="xsd:integer"></xsl:variable>
                <xsl:variable name="split-index" select="$compareIndex - $preTextLength" as="xsd:integer"></xsl:variable>
                <xsl:if test="($sum ge $compareIndex) and ($compareIndex gt $preTextLength)">
                    <data split-index="{$split-index}" text-id="{generate-id(.)}"> 
                        <xsl:copy-of select="$nodeContent"/> 
                    </data> 
                </xsl:if>
            </xsl:for-each>
              </xsl:for-each>
              </xsl:variable> 
© Stack Overflow or respective owner