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: 457

Filed under:
|
|
|

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

Related posts about xslt

Related posts about xsl