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