xslt - Ordering nodes in XSL Transformation -
source xml:
<?xml version="1.0" encoding="utf-8"?> <bigdata version="2.1" xmlns="bank.xsd"> <insidedata type="plan" name="testbank" id="10"> <header> <log datetime="2013-07-27t15:52:30"/> </header> <object class="bank" distname="city-1/abc-1/bank-1" operation="create" timestamp="2013-07-27t15:48:20"/> <object class="branchitemperiod" distname="city-1/abc-1/bank-1/branch-1/branchitem-1/branchitemperiod-1" operation="create" timestamp="2013-07-27t15:51:25"> <p name="week">0</p> <p name="interval">10</p> </object> <object class="branchitemperiod" distname="city-1/abc-1/bank-1/branch-1/branchitem-2/branchitemperiod-2" operation="update" timestamp="2013-07-27t15:51:25"> <p name="week">0</p> <p name="interval">10</p> </object> <object class="branch" distname="city-1/abc-1/bank-1/branch-1" operation="create" timestamp="2013-07-27t15:48:31"/> <object class="branchitem" distname="city-1/abc-1/bank-1/branch-1/branchitem-1" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="branchitem" distname="city-1/abc-1/bank-1/branch-1/branchitem-2" operation="update" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="sleep" distname="city-1/abc-1/sleep-1" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="dance" distname="city-1/abc-1/dance-5" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> </insidedata> </bigdata>
transformation xsl :
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0" xmlns:x="bank.xsd" exclude-result-prefixes="x"> <xsl:output encoding="utf-8" indent="yes" method="xml"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="x:object[@class = 'bank' ]"> </xsl:template> <xsl:template match="x:object[@class = 'branch' ]"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="distname"> <xsl:value-of select="concat(substring-before( @distname,'bank-1/' ), substring-after( @distname, 'bank-1/'))"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <xsl:template match="x:object[@class = 'branchitem' ]"> <xsl:variable name="branchitem" select="."/> <xsl:choose> <xsl:when test="$branchitem/@operation='update' , not(contains($branchitem/@distname, 'jobs_created_using_ne_local_ui'))"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="operation">delete</xsl:attribute> <xsl:attribute name="distname"> <xsl:value-of select="concat(substring-before( @distname,'bank-1/' ), substring-after( @distname, 'bank-1/'))"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="operation">create</xsl:attribute> <xsl:attribute name="distname"> <xsl:value-of select="concat(substring-before( @distname,'bank-1/' ), substring-after( @distname, 'bank-1/'))"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="distname"> <xsl:value-of select="concat(substring-before( @distname,'bank-1/' ), substring-after( @distname, 'bank-1/'))"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="x:object[@class = 'branchitemperiod' ]"> <xsl:variable name="branchpeiod" select="."/> <xsl:choose> <xsl:when test="$branchpeiod/@operation='update' , not(contains($branchpeiod/@distname, 'jobs_created_using_ne_local_ui'))"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="operation">create</xsl:attribute> <xsl:attribute name="distname"> <xsl:value-of select="concat(substring-before( @distname,'bank-1/' ), substring-after( @distname, 'bank-1/'))"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="distname"> <xsl:value-of select="concat(substring-before( @distname,'bank-1/' ), substring-after( @distname, 'bank-1/'))"/> </xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
output xml :
<?xml version="1.0" encoding="utf-8"?> <bigdata xmlns="bank.xsd" version="2.1"> <insidedata type="plan" name="testbank" id="10"> <header> <log datetime="2013-07-27t15:52:30"/> </header> <object class="branchitemperiod" distname="city-1/abc-1/branch-1/branchitem-1/branchitemperiod-1" operation="create" timestamp="2013-07-27t15:51:25"> <p name="week">0</p> <p name="interval">10</p> </object> <object class="branchitemperiod" distname="city-1/abc-1/branch-1/branchitem-2/branchitemperiod-2" operation="create" timestamp="2013-07-27t15:51:25"> <p name="week">0</p> <p name="interval">10</p> </object> <object class="branch" distname="city-1/abc-1/branch-1" operation="create" timestamp="2013-07-27t15:48:31"/> <object class="branchitem" distname="city-1/abc-1/branch-1/branchitem-1" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="branchitem" distname="city-1/abc-1/branch-1/branchitem-2" operation="delete" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="branchitem" distname="city-1/abc-1/branch-1/branchitem-2" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="sleep" distname="city-1/abc-1/sleep-1" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="dance" distname="city-1/abc-1/dance-5" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> </insidedata> </bigdata>
desired output xml:
<?xml version="1.0" encoding="utf-8"?> <bigdata xmlns="bank.xsd" version="2.1"> <insidedata type="plan" name="testbank" id="10"> <header> <log datetime="2013-07-27t15:52:30"/> </header> <object class="branch" distname="city-1/abc-1/branch-1" operation="create" timestamp="2013-07-27t15:48:31"/> <object class="branchitem" distname="city-1/abc-1/branch-1/branchitem-1" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="branchitemperiod" distname="city-1/abc-1/branch-1/branchitem-1/branchitemperiod-1" operation="create" timestamp="2013-07-27t15:51:25"> <p name="week">0</p> <p name="interval">10</p> </object> <object class="branchitem" distname="city-1/abc-1/branch-1/branchitem-2" operation="delete" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="branchitem" distname="city-1/abc-1/branch-1/branchitem-2" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="branchitemperiod" distname="city-1/abc-1/branch-1/branchitem-2/branchitemperiod-2" operation="create" timestamp="2013-07-27t15:51:25"> <p name="week">0</p> <p name="interval">10</p> </object> <object class="sleep" distname="city-1/abc-1/sleep-1" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> <object class="dance" distname="city-1/abc-1/dance-5" operation="create" timestamp="2013-07-27t15:50:42"> <p name="opendate">2013-07-27</p> <p name="closedate">2013-07-29</p> </object> </insidedata> </bigdata>
i achieve of desired output except few...
- i want output sorted based on distname attribute of object nodes.
- i want sort happen child nodes class names branch , branchitem , branchitemperiod.
- here try update delete , create operation, want maintain order of delete , create in present transformation logic or else can happen sort first based on above criteria , apply other transformation logic.
any suggestion or highly appreciated.
i think need here template matches insidedata element, can select child object elements in order require.
you first start outputting non-"object" elements, assuming these come before object elements.
<xsl:apply-templates select="@*|node()[not(self::x:object)]"/>
then select object elements class attribute desire, sorting in order require too:
<xsl:apply-templates select="x:object[@class='branch' or @class='branchitem' or @class='branchitemperiod']"> <xsl:sort select="@distname"/> </xsl:apply-templates>
finally, output object elements have the class attributes.
<xsl:apply-templates select="x:object[not(@class='branch' or @class='branchitem' or @class='branchitemperiod')]"/>
try adding template xslt see how on:
<xsl:template match="x:insidedata"> <xsl:copy> <xsl:apply-templates select="@*|node()[not(self::x:object)]"/> <xsl:apply-templates select="x:object[@class='branch' or @class='branchitem' or @class='branchitemperiod']"> <xsl:sort select="@distname"/> </xsl:apply-templates> <xsl:apply-templates select="x:object[not(@class='branch' or @class='branchitem' or @class='branchitemperiod')]"/> </xsl:copy> </xsl:template>
Comments
Post a Comment