Perhaps the thing that's making this slow is that for each <row> element
you do
<xsl:template match="/inputDocument/row">
<xsl:for-each select="child::*">
<xsl:if test="name=/inputDocument/header/name[4]">
<xsl:call-template name="generateOutputRecord">
where generateOutputRecord then does:
<xsl:for-each select="../*">
<xsl:call-template name="processField">
which means that for every cell you are processing every cell, in other
words it's O(n^2) in the number of cells per row. That shouldn't matter
too much if there are only five cells per row as in your example: but
perhaps there are actually more?
It would be useful to know (a) what the actual data sizes are like, (b)
what performance you are actually getting (and with what processor), and
(c) how the performance scales as the data size increases.
For all that we know, you could simply be thrashing for lack of memory.
Michael Kay
-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of
Ray Tayek
Sent: 30 December 2003 19:41
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] anyway obvious way to speed this tranfrom up?
hi, newbie managed to get something to work, but it's *real* slow.
the xslt's are generated by a program, so they can not be
hand tuned, but maybe there is a way to do some things faster?
The xml input comes from a spreadsheet via a .csv file, so
the original names in the <header> can contains spaces and
strange characters, but the names in the <cell>'s are legal
database names.
any clues will be appreciated.
thanks
Xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes"/>
<xsl:template match="/inputDocument">
<xsl:element name="outputDocument">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="/inputDocument/header">
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
<xsl:element name="csvHeader">
<xsl:element name="copy1"/><xsl:element
name="renamed1"/><xsl:element name="new3"/><xsl:element
name="new1"/><xsl:element name="new2"/><xsl:element
name="new4"/><xsl:element name="new5"/>
</xsl:element>
</xsl:template>
<xsl:template match="/inputDocument/header/*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/inputDocument/row">
<xsl:for-each select="child::*">
<xsl:if
test="name=/inputDocument/header/name[4]">
<xsl:call-template
name="generateOutputRecord">
<xsl:with-param name="index"
select="'4'"/>
<xsl:with-param name="name1"
select="'new1'"/>
<xsl:with-param
name="value1" select="'new1ValueFromSpecial1Name'"/>
<xsl:with-param name="name2"
select="'new2'"/>
<xsl:with-param
name="value2" select="'new2ValueFromSpecial1Name'"/>
<xsl:with-param name="name3"
select="'new4'"/>
<xsl:with-param name="value3"
select="''"/>
<xsl:with-param name="name4"
select="'new5'"/>
<xsl:with-param name="value4"
select="''"/>
</xsl:call-template>
</xsl:if>
<xsl:if
test="name=/inputDocument/header/name[5]">
<xsl:call-template
name="generateOutputRecord">
<xsl:with-param name="index"
select="'5'"/>
<xsl:with-param name="name1"
select="'new1'"/>
<xsl:with-param name="value1"
select="''"/>
<xsl:with-param name="name2"
select="'new2'"/>
<xsl:with-param
name="value2" select="'new2ValueFromSpecial2Name'"/>
<xsl:with-param name="name3"
select="'new4'"/>
<xsl:with-param
name="value3" select="'new4ValueFromSpecial2Name'"/>
<xsl:with-param name="name4"
select="'new5'"/>
<xsl:with-param
name="value4" select="'new5ValueFromSpecial2Name'"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="generateOutputRecord">
<xsl:param name="index" select="0"/>
<xsl:param name="name1" select="defaultValueName"/>
<xsl:param name="value1" select="defaultValueValue"/>
<xsl:param name="name2" select="defaultValueName"/>
<xsl:param name="value2" select="defaultValueValue"/>
<xsl:param name="name3" select="defaultValueName"/>
<xsl:param name="value3" select="defaultValueValue"/>
<xsl:param name="name4" select="defaultValueName"/>
<xsl:param name="value4" select="defaultValueValue"/>
<xsl:element name="row">
<xsl:attribute name="iln"><xsl:number
count="row"/></xsl:attribute>
<xsl:for-each select="../*">
<xsl:call-template name="processField">
<xsl:with-param name="xindex"
select="$index"/>
</xsl:call-template>
</xsl:for-each>
<xsl:call-template name="addNewFields">
<xsl:with-param name="xname1"
select="$name1"/>
<xsl:with-param name="xvalue1"
select="$value1"/>
<xsl:with-param name="xname2"
select="$name2"/>
<xsl:with-param name="xvalue2"
select="$value2"/>
<xsl:with-param name="xname3"
select="$name3"/>
<xsl:with-param name="xvalue3"
select="$value3"/>
<xsl:with-param name="xname4"
select="$name4"/>
<xsl:with-param name="xvalue4"
select="$value4"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template name="addNewFields">
<xsl:param name="xname1" select="defaultValueName"/>
<xsl:param name="xvalue1" select="defaultValueValue"/>
<xsl:param name="xname2" select="defaultValueName"/>
<xsl:param name="xvalue2" select="defaultValueValue"/>
<xsl:param name="xname3" select="defaultValueName"/>
<xsl:param name="xvalue3" select="defaultValueValue"/>
<xsl:param name="xname4" select="defaultValueName"/>
<xsl:param name="xvalue4" select="defaultValueValue"/>
<xsl:element name="{$xname1}">
<xsl:value-of select="$xvalue1"/>
</xsl:element>
<xsl:element name="{$xname2}">
<xsl:value-of select="$xvalue2"/>
</xsl:element>
<xsl:element name="{$xname3}">
<xsl:value-of select="$xvalue3"/>
</xsl:element>
<xsl:element name="{$xname4}">
<xsl:value-of select="$xvalue4"/>
</xsl:element>
</xsl:template>
<xsl:template name="processField">
<xsl:param name="xindex" select="0"/>
<xsl:choose>
<xsl:when
test="name=/inputDocument/header/name[1]">
<xsl:element name="{name}">
<xsl:choose>
<xsl:when
test="value='oldValue1'"><xsl:value-of
select="'newValue1'"/></xsl:when>
<xsl:when
test="value='oldValue2'"><xsl:value-of
select="'newValue2'"/></xsl:when>
<xsl:otherwise>
<xsl:value-of
select="value"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:when
test="name=/inputDocument/header/name[2]"/>
<xsl:when
test="name=/inputDocument/header/name[3]">
<xsl:element name="renamed1">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:when>
<xsl:when
test="name=/inputDocument/header/name[4]
and $xindex='4'">
<xsl:element name="new3">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:when>
<xsl:when
test="name=/inputDocument/header/name[5]
and $xindex='5'">
<xsl:element name="new3">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
xml input file:
<?xml version="1.0" encoding="UTF-8"?>
<inputDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="U:\projects\tender\tender2\com\
ediidea\tender
\testFiles\inputDocument.xsd">
<header>
<name icn="1">copy1</name>
<name icn="2">remove1</name>
<name icn="3">rename1</name>
<name icn="4">special1</name>
<name icn="5">special2</name>
</header>
<row>
<cell>
<name>copy1</name>
<value>copy1Value1</value>
</cell>
<cell>
<name>remove1</name>
<value>remove1Value1</value>
</cell>
<cell>
<name>rename1</name>
<value>rename1Value1</value>
</cell>
<cell>
<name>special1</name>
<value>special1Value1</value>
</cell>
<cell>
<name>special2</name>
<value>special2Value1</value>
</cell>
</row>
<row>
<cell>
<name>copy1</name>
<value>copy1Value2</value>
</cell>
<cell>
<name>remove1</name>
<value>remove1Value2</value>
</cell>
<cell>
<name>rename1</name>
<value>rename1Value2</value>
</cell>
<cell>
<name>special1</name>
<value>special1Value2</value>
</cell>
<cell>
<name>special2</name>
<value>special2Value2</value>
</cell>
</row>
<row>
<cell>
<name>copy1</name>
<value>oldValue1</value>
</cell>
<cell>
<name>remove1</name>
<value>remove1Value3</value>
</cell>
<cell>
<name>rename1</name>
<value>rename1Value3</value>
</cell>
<cell>
<name>special1</name>
<value>special1Value3</value>
</cell>
<cell>
<name>special2</name>
<value>special2Value3</value>
</cell>
</row>
<row>
<cell>
<name>copy1</name>
<value>oldValue2</value>
</cell>
<cell>
<name>remove1</name>
<value>remove1Value4</value>
</cell>
<cell>
<name>rename1</name>
<value>rename1Value4</value>
</cell>
<cell>
<name>special1</name>
<value>special1Value4</value>
</cell>
<cell>
<name>special2</name>
<value>special2Value4</value>
</cell>
</row>
<row>
<cell>
<name>copy1</name>
<value/>
</cell>
<cell>
<name>remove1</name>
<value/>
</cell>
<cell>
<name>rename1</name>
<value/>
</cell>
<cell>
<name>special1</name>
<value/>
</cell>
<cell>
<name>special2</name>
<value/>
</cell>
</row>
</inputDocument>
xml output file:
<?xml version="1.0" encoding="UTF-8"?>
<outputDocument>
<header>
<name icn="1">copy1</name>
<name icn="2">remove1</name>
<name icn="3">rename1</name>
<name icn="4">special1</name>
<name icn="5">special2</name>
</header>
<csvHeader>
<copy1/>
<renamed1/>
<new3/>
<new1/>
<new2/>
<new4/>
<new5/>
</csvHeader>
<row iln="1">
<copy1>copy1Value1</copy1>
<renamed1>rename1Value1</renamed1>
<new3>special1Value1</new3> <new1>new1ValueFromSpecial1Name</new1>
<new2>new2ValueFromSpecial1Name</new2>
<new4/>
<new5/>
</row>
<row iln="1">
<copy1>copy1Value1</copy1>
<renamed1>rename1Value1</renamed1>
<new3>special2Value1</new3>
<new1/>
<new2>new2ValueFromSpecial2Name</new2>
<new4>new4ValueFromSpecial2Name</new4>
<new5>new5ValueFromSpecial2Name</new5>
</row>
<row iln="2">
<copy1>copy1Value2</copy1>
<renamed1>rename1Value2</renamed1>
<new3>special1Value2</new3> <new1>new1ValueFromSpecial1Name</new1>
<new2>new2ValueFromSpecial1Name</new2>
<new4/>
<new5/>
</row>
<row iln="2">
<copy1>copy1Value2</copy1>
<renamed1>rename1Value2</renamed1>
<new3>special2Value2</new3>
<new1/>
<new2>new2ValueFromSpecial2Name</new2>
<new4>new4ValueFromSpecial2Name</new4>
<new5>new5ValueFromSpecial2Name</new5>
</row>
<row iln="3">
<copy1>newValue1</copy1>
<renamed1>rename1Value3</renamed1>
<new3>special1Value3</new3> <new1>new1ValueFromSpecial1Name</new1>
<new2>new2ValueFromSpecial1Name</new2>
<new4/>
<new5/>
</row>
<row iln="3">
<copy1>newValue1</copy1>
<renamed1>rename1Value3</renamed1>
<new3>special2Value3</new3>
<new1/>
<new2>new2ValueFromSpecial2Name</new2>
<new4>new4ValueFromSpecial2Name</new4>
<new5>new5ValueFromSpecial2Name</new5>
</row>
<row iln="4">
<copy1>newValue2</copy1>
<renamed1>rename1Value4</renamed1>
<new3>special1Value4</new3> <new1>new1ValueFromSpecial1Name</new1>
<new2>new2ValueFromSpecial1Name</new2>
<new4/>
<new5/>
</row>
<row iln="4">
<copy1>newValue2</copy1>
<renamed1>rename1Value4</renamed1>
<new3>special2Value4</new3>
<new1/>
<new2>new2ValueFromSpecial2Name</new2>
<new4>new4ValueFromSpecial2Name</new4>
<new5>new5ValueFromSpecial2Name</new5>
</row>
<row iln="5">
<copy1/>
<renamed1/>
<new3/>
<new1>new1ValueFromSpecial1Name</new1>
<new2>new2ValueFromSpecial1Name</new2>
<new4/>
<new5/>
</row>
<row iln="5">
<copy1/>
<renamed1/>
<new3/>
<new1/>
<new2>new2ValueFromSpecial2Name</new2>
<new4>new4ValueFromSpecial2Name</new4>
<new5>new5ValueFromSpecial2Name</new5>
</row>
</outputDocument>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list