How to Optimize XSLT for Referencing data in other XMLs -
in input xml file, along static columns, columns expecting data other files (reference)is available. each reference, input xml has separate row same id or uid.
the output file has have references , relations in 1 row (based on id or uid)
i wrote xslt transformation also. xslt faster when row count less (< 100 or < 200). but, count grows, output xml generation taking long time (for count of 1000 rows, around 30 mins).
i using
<xsl:for-each select="z:row/@id[generate-id() = generate-id(key('uniqueid',.))]">
in xslt. because same id in each row of input xml, has check multiple references (like section) , relations (like child) , populate same columns
input raw xml file.
<xml xmlns:dt="uuid:c2f41010-65b3-11d1-a29f-00aa00c14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:s="uuid:bdc6e3f0-6da3-11d1-a2a3-00aa00c14882" xmlns:z="#rowsetschema"> <rs:data> <z:row uid="parent_001_1221ad_a878" groupid="" grouprel="" id="37" name="outer asset details" relproduct="line1" reluid="child1_101_9899_9poou99" relname="child1" reltype="child" size="22"/> <z:row uid="parent_001_1221ad_a878" groupid="" grouprel="" id="37" name="outer asset details" relproduct="line1" reluid="child2_201_5646546_9890pbs" relname="child1" reltype="child" size="22"/> <z:row uid="parent_001_1221ad_a878" groupid="" grouprel="" id="37" name="outer asset details" relproduct="line1" reluid="sec_999_99565_998afsd" relname="hydraulic section" reltype="section" size="22"/> </rs:data>
child.xml
<child xsi:nonamespaceschemalocation="../xsd/child.xsd" file="child" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <row uid="child1_101_9899_9poou99"> <name>child1</name> <description>this has details hydraulic sections of automobile</description> </row> <row uid="child2_201_5646546_9890pbs"> <name>child2</name> <description>this has details manual sections of automobile</description> </row>
section.xml
<section xsi:nonamespaceschemalocation="../xsd/section.xsd" file="section" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <row uid="sec_999_99565_998afsd"> <name>hydraulic section</name> <description>this has details sections in hydraulic systems used.</description> </row>
xslt file
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:s="uuid:bdc6e3f0-6da3-11d1-a2a3-00aa00c14882" xmlns:dt="uuid:c2f41010-65b3-11d1-a29f-00aa00c14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#rowsetschema" exclude-result-prefixes="s dt z rs msxsl" xmlns:msxsl="urn:schemas-microsoft-com:xslt"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/> <xsl:key name="uniqueid" match="z:row/@id" use="."/> <xsl:template match="/"> <parent xsi:nonamespaceschemalocation="../xsd/parent.xsd" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" file="parent"> <xsl:for-each select="xml"> <xsl:apply-templates select="rs:data"/> </xsl:for-each> </parent> </xsl:template> <xsl:template match="rs:data"> <xsl:for-each select="z:row/@id[generate-id() = generate-id(key('uniqueid',.))]"> <xsl:variable name="frid"> <xsl:value-of select="current()"/> </xsl:variable> <xsl:variable name="curnset" select="//z:row[@id=$frid]"/> <xsl:copy-of select="current()"/> <record> <xsl:attribute name="uid"><xsl:value-of select="$curnset/@uid"/></xsl:attribute> <xsl:element name="size"> <xsl:value-of select="$curnset/@size"/> </xsl:element> <xsl:element name="child"> <xsl:apply-templates select="$curnset[@reltype='child']" mode="relations"> <xsl:with-param name="reltype" select="'child'"/> <xsl:with-param name="dstfilename" select="'../files/child.xml'"/> </xsl:apply-templates> </xsl:element> <xsl:element name="section"> <xsl:apply-templates select="$curnset[@reltype='section']" mode="references"> <xsl:with-param name="reltype" select="'section'"/> <xsl:with-param name="dstfilename" select="'../files/section.xml'"/> </xsl:apply-templates> </xsl:element> </record> </xsl:for-each> </xsl:template> <xsl:template match="z:row" mode="relations"> <xsl:param name="reltype"/> <xsl:param name="dstfilename"/> <xsl:element name="{$reltype}"> <xsl:attribute name="destinationkey"><xsl:value-of select="@reluid"/></xsl:attribute> <xsl:attribute name="relfilepath"><xsl:value-of select="$dstfilename"/></xsl:attribute> <xsl:attribute name="sequencenumber"><xsl:value-of select="position()"/></xsl:attribute> <xsl:value-of select="@relname"/> </xsl:element> </xsl:template> <xsl:template match="z:row" mode="references"> <xsl:param name="dstfilename"/> <xsl:attribute name="destinationkey"><xsl:value-of select="@reluid"/></xsl:attribute> <xsl:attribute name="relfilepath"><xsl:value-of select="$dstfilename"/></xsl:attribute> <xsl:attribute name="sequencenumber"><xsl:value-of select="position()"/></xsl:attribute> <xsl:value-of select="@relname"/> </xsl:template>
output.xml
<parent xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nonamespaceschemalocation="../xsd/parent.xsd" file="parent" id="37"> <record uid="parent_001_1221ad_a878"> <size>22</size> <child> <child destinationkey="child1_101_9899_9poou99" relfilepath="../files/child.xml" sequencenumber="1">child1</child> <child destinationkey="child2_201_5646546_9890pbs" relfilepath="../files/child.xml" sequencenumber="2">child1</child> </child> <section destinationkey="sec_999_99565_998afsd" relfilepath="../files/section.xml" sequencenumber="1">hydraulic section</section> </record>
please me in optimizing xslt, output file generated faster
consider use
<xsl:key name="uniqueid" match="z:row" use="@id"/>
then
<xsl:for-each select="z:row/@id[generate-id() = generate-id(key('uniqueid',.))]"> <xsl:variable name="frid"> <xsl:value-of select="current()"/> </xsl:variable> <xsl:variable name="curnset" select="//z:row[@id=$frid]"/>
can replaced with
<xsl:for-each select="z:row[generate-id() = generate-id(key('uniqueid', @id))]"> <xsl:variable name="frid" select="@id"/> <xsl:variable name="curnset" select="key('uniqueid', @id"/>
i not sure need variable frid
@ defining select
attribute instead of nested value-of
consuming less resources.
to make
<xsl:apply-templates select="$curnset[@reltype='child']" mode="relations">
more efficient define key
<xsl:key name="rel" match="z:row" use="concat(@id, '|', @reltype)"/>
then use
<xsl:apply-templates select="key('rel', concat(@id, '|', 'child')" mode="relations">
then use same approach other apply-templates.
all of above untested should give idea.
Comments
Post a Comment