Xslt optimization: accessing multiple children or using a variable

I need information to optimize my xslt.

In my template, I refer to the descendant several times, for example, for example:

<xsl:template match="user">
 <h1><xsl:value-of select="address/country"/></h1>
 <p><xsl:value-of select="address/country"/></p>
 <p><xsl:value-of select="address/country"/></p>
  ... more and more...
 <p><xsl:value-of select="address/country"/></p>
</xsl:template>

It would be better to store the contents of the child in a variable and directly call the variable to avoid parsing the tree each time:

<xsl:template match="user">
 <xsl:variable name="country" select="address/country"/>
 <h1><xsl:value-of select="$country"/></h1>
 <p><xsl:value-of select="$country"/></p>
 <p><xsl:value-of select="$country"/></p>
  ... more and more...
 <p><xsl:value-of select="$country"/></p>
</xsl:template>

Or will using a variable consume more resources than rearing a tree several times?

+3
source share
3 answers

Typically, an XML file is parsed as a whole and stored in memory as XDM . So, I suppose that

than parsing a tree several times

XML- . , :

enter image description here
( Michael Kay XSLT 2.0 XPath 2.0, . 43)

, xsl:variable node (, , ), , .

, ? , ( "" )?

, XSLT-, . - .

, , . XML , .

, , , ( " " ).


: - , .

, :

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/root">
      <xsl:copy>
         <xsl:variable name="var" select="node/subnode"/>
         <subnode nr="1">
            <xsl:value-of select="$var"/>
         </subnode>
         <subnode nr="2">
            <xsl:value-of select="$var"/>
         </subnode>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/root">
      <xsl:copy>
         <subnode nr="1">
            <xsl:value-of select="node/subnode"/>
         </subnode>
         <subnode nr="2">
            <xsl:value-of select="node/subnode"/>
         </subnode>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

XML:

<root>
   <node>
      <subnode>helloworld</subnode>
   </node>
</root>

. , , 100 ( "-t -repeat: 100 Saxon" ):

with variable: 9 ms
without variable: 9 ms

, XSLT-.

+4

: .

  • , XSLT , , .

  • , , , , .

- .

, , , .

, , , . , , , .

+2

:. , , , , . selection [ ], . [ , , , <xsl:copy-of select="$country"/>, .]

, :

<xsl:apply-template select="address/country"/>
[...]
<xsl:template match="address/country">
   <h1><xsl:value-of select="."/></h1>
   <p><xsl:value-of select="."/></p>
   [...]
</xsl:template>

@Mathias_MΓΌller , "... ...", . XSLT 2.0 for-each:

<xsl:for-each select="1 to 100">
  <p><xsl:value-of select="."/></p>
</xsl:for-each>

XSLT >= 2.0, , call-template [ ]:

<xsl:call-template name="ntimes">
  <xsl:with-param name="counter" select="100"/>
</xsl:call-template>
[...]
<xsl:template name="ntimes">
  <xsl:param name="counter" select="0"/>
  <xsl:if test="$counter > 0">
    <xsl:choose>
      <xsl:when test="$counter = 1">
        <xsl:apply-template select="address/country"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="half" select="floor($counter div 2)"/>
        <xsl:call-template name="ntimes">
          <xsl:with-param name="counter" select="$half"/>
        </xsl:call-template>
        <xsl:call-template name="ntimes">
          <xsl:with-param name="counter" select="$counter - $half"/>
        </xsl:call-template>
       [...]

.

Honestly, I don't know anything about performance and optimization in XSLT. I never thought it was worth the effort, given that most of the time I use XSLT processors written in Java and that I use large input files, while theres still whole, several hundred MB of RAM. consuming jvm to run up to ..?

+1
source

All Articles