0

We use xslt 1.0 with Xpath 1.0 and XalanJ 2.7.1. We make profiling of our templates and try to reduce the call time. So out biggest hotspot is:

<xsl:template name="tplAttribute">
    <xsl:param name="sourceObject" />
    <xsl:param name="sourceName" />
    <xsl:param name="targetName" />

    <xsl:variable name="sourceAttribute" select="$sourceObject/attribute[@name = $sourceName]" />
    <xsl:if test="$sourceAttribute">
        <dcx:attribute name="{$targetName}">
            <xsl:value-of select="$sourceAttribute" />
        </attribute>
    </xsl:if>
</xsl:template>

The average time during 871 hits is 103 and for variable 59ms.

Is there any better solution in order to reduce the time of the transformation?

Edit: Input structure template calls when process 'sourceObject':

object
  tplAttribute 
  tplAttribute
  tplAttributeDefault
  tplAttribute
  tplAttributeSomeDifferentLogic
  tplAttribute
  tplAttributeOther

enter image description here

Xelian
  • 16,680
  • 25
  • 99
  • 152
  • How many "attribute" elements would typically be found as children of $sourceObject? – Michael Kay Oct 03 '16 at 16:43
  • Depends but from 20 to 100. So we have $sourceObject and in it we have to find a specific attribute in it. But then we have to search for another and so on. In some situations we have different logic - tplAttributeOther etc. So I am not sure does the creation of the variable slows the process or if we have two selects instead of sourceAttribute var will be faster based on the processor optimizations? – Xelian Oct 04 '16 at 08:17
  • I don't know the internals of Xalan. Saxon-EE will probably create an index to evaluate this one - give it a try and let us know the results. – Michael Kay Oct 04 '16 at 09:20
  • In our organization we can not use Saxon-EE because of the license. I can try with Oxigen but the result will not be useful for me(probably I will regret that we do not use Saxon :) – Xelian Oct 04 '16 at 09:54

1 Answers1

0

Define a key <xsl:key name="att-by-name" match="attribute" use="@name"/> and then use

<xsl:for-each select="$sourceObject">
  <xsl:if test="key('att-by-name', $sourceName)">
            <dcx:attribute name="{$targetName}">
                <xsl:value-of select="key('att-by-name', $sourceName)" />
            </attribute>
  </xsl:if>
</xsl:for-each>

instead of

    <xsl:variable name="sourceAttribute" select="$sourceObject/attribute[@name = $sourceName]" />
    <xsl:if test="$sourceAttribute">
        <dcx:attribute name="{$targetName}">
            <xsl:value-of select="$sourceAttribute" />
        </attribute>
    </xsl:if>

You might need to show us the exact structure of the document with sourceObject, the key based approach as shown will work if the name attribute of attribute elements identifies the attribute element(s) you are looking for in the complete document. If you are only looking into a subtree then you might need to include an id in the key value.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110