Friday 15 August 2014

hierarchical - Extreme XSLT 1 Flat to Hierarchial Transform needed take 2 -



hierarchical - Extreme XSLT 1 Flat to Hierarchial Transform needed take 2 -

i fighting pretty extreme case of transforming flat xml hierarchical one. i'm stuck using xslt 1.0. acting wants i'm trying, not quite there. you'll have run see. need head around how these keys work. examples find based upon value of attribute... , not cross-reference between different nodes.

here input:

<?xml version="1.0" encoding="utf-8"?> <env:envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:header/> <env:body> <tns:getdatars xmlns:tns="http://www.myco.com/dataservice"> <tns:acknowledgement>process completed successfully.</tns:acknowledgement> <tns:customer> <tns:customerid>210</tns:customerid> <tns:visitid>12</tns:visitid> <tns:storeid>1</tns:storeid> <tns:storeorder>28</tns:storeorder> <tns:itemid>1</tns:itemid> <tns:customersalesdate>2014-09-26</tns:customersalesdate> </tns:customer> <tns:customer> <tns:customerid>210</tns:customerid> <tns:visitid>12</tns:visitid> <tns:storeid>1</tns:storeid> <tns:storeorder>28</tns:storeorder> <tns:itemid>3</tns:itemid> <tns:customersalesdate>2014-09-26</tns:customersalesdate> </tns:customer> <tns:customer> <tns:customerid>211</tns:customerid> <tns:visitid>31</tns:visitid> <tns:storeid>2</tns:storeid> <tns:storeorder>48</tns:storeorder> <tns:itemid>2</tns:itemid> <tns:customersalesdate>2014-09-26</tns:customersalesdate> </tns:customer> <tns:customer> <tns:customerid>211</tns:customerid> <tns:visitid>31</tns:visitid> <tns:storeid>2</tns:storeid> <tns:storeorder>48</tns:storeorder> <tns:itemid>4</tns:itemid> <tns:customersalesdate>2014-09-26</tns:customersalesdate> </tns:customer> <tns:item> <tns:customerid>210</tns:customerid> <tns:visitid>12</tns:visitid> <tns:storeid>1</tns:storeid> <tns:itemid>1</tns:itemid> <tns:unitprice>2.95</tns:unitprice> <tns:quantity>4</tns:quantity> </tns:item> <tns:item> <tns:customerid>211</tns:customerid> <tns:visitid>31</tns:visitid> <tns:storeid>2</tns:storeid> <tns:itemid>2</tns:itemid> <tns:unitprice>3.29</tns:unitprice> <tns:quantity>2</tns:quantity> </tns:item> <tns:item> <tns:customerid>210</tns:customerid> <tns:visitid>12</tns:visitid> <tns:storeid>1</tns:storeid> <tns:itemid>3</tns:itemid> <tns:unitprice>4.99</tns:unitprice> <tns:quantity>1</tns:quantity> </tns:item> <tns:item> <tns:customerid>211</tns:customerid> <tns:visitid>31</tns:visitid> <tns:storeid>2</tns:storeid> <tns:itemid>4</tns:itemid> <tns:unitprice>6.95</tns:unitprice> <tns:quantity>2</tns:quantity> </tns:item> </tns:getdatars> </env:body> </env:envelope>

here xslt:

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:tns="http://www.myco.com/dataservice"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="storekey" match="*[local-name() = 'storeid']" use="."/> <xsl:key name="orderkey" match="*[local-name() = 'storeorder']" use="."/> <xsl:key name="customerkey" match="*[local-name() = 'customerid']" use="."/> <xsl:key name="itemkey" match="*[local-name() = 'itemid']" use="."/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="*[local-name() = 'getdatars']"> <xsl:copy> <tns:stores> <xsl:for-each select="//*[local-name() = 'storeid'][count(. | key('storekey', .)) > 0]"> <xsl:apply-templates select="."/> </xsl:for-each> </tns:stores> </xsl:copy> </xsl:template> <xsl:template match="*[local-name() = 'storeid']"> <tns:store> <xsl:copy-of select="."/> <tns:orders> <xsl:for-each select="../*[local-name() = 'storeorder'][count(. | key('orderkey', .)) > 0]"> <xsl:apply-templates select="."/> </xsl:for-each> </tns:orders> </tns:store> </xsl:template> <xsl:template match="*[local-name() = 'storeorder']"> <tns:order><xsl:value-of select="."/></tns:order> <tns:salesdate><xsl:value-of select="../*[local-name() = 'customersalesdate']"/></tns:salesdate> <tns:customers> <xsl:for-each select="../*[local-name() = 'customerid'][count(. | key('customerkey', .)) > 0]"> <xsl:apply-templates select="."/> </xsl:for-each> </tns:customers> </xsl:template> <xsl:template match="*[local-name() = 'customerid']"> <tns:customer> <xsl:copy-of select="."/> <xsl:copy-of select="../*[local-name() = 'visitid']"/> <tns:items> <xsl:for-each select="../*[local-name() = 'itemid'][count(. | key('itemkey', .)) > 0]"> <xsl:apply-templates select="."/> </xsl:for-each> </tns:items> </tns:customer> </xsl:template> <xsl:template match="*[local-name() = 'itemid']"> <tns:item> <xsl:copy-of select="."/> <xsl:copy-of select="../*[local-name() = 'unitprice']"/> <xsl:copy-of select="../*[local-name() = 'quantity']"/> </tns:item> </xsl:template> </xsl:stylesheet>

here desired output:

<?xml version="1.0" encoding="utf-8"?> <env:envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:header/> <env:body> <tns:getdatars xmlns:tns="http://www.myco.com/dataservice"> <tns:acknowledgement>process completed successfully.</tns:acknowledgement> <tns:stores> <tns:store> <tns:storeid>1</tns:storeid> <tns:orders> <tns:order>28</tns:order> <tns:salesdate>2014-09-26</tns:salesdate> <tns:customers> <tns:customer> <tns:customerid>210</tns:customerid> <tns:visitid>12</tns:visitid> <tns:items> <tns:item> <tns:itemid>1</tns:itemid> <tns:unitprice>2.95</tns:unitprice> <tns:quantity>4</tns:quantity> </tns:item> <tns:item> <tns:itemid>3</tns:itemid> <tns:unitprice>4.99</tns:unitprice> <tns:quantity>1</tns:quantity> </tns:item> </tns:items> </tns:customer> </tns:customers> </tns:orders> </tns:store> <tns:store> <tns:storeid>2</tns:storeid> <tns:orders> <tns:order>48</tns:order> <tns:salesdate>2014-09-26</tns:salesdate> <tns:customers> <tns:customer> <tns:customerid>211</tns:customerid> <tns:visitid>31</tns:visitid> <tns:items> <tns:item> <tns:itemid>2</tns:itemid> <tns:unitprice>3.29</tns:unitprice> <tns:quantity>2</tns:quantity> </tns:item> <tns:item> <tns:itemid>4</tns:itemid> <tns:unitprice>6.95</tns:unitprice> <tns:quantity>2</tns:quantity> </tns:item> </tns:items> </tns:customer> </tns:customers> </tns:orders> </tns:store> </tns:stores> </tns:getdatars> </env:body> </env:envelope>

xslt hierarchical flat

No comments:

Post a Comment