grouping in xslt 1.0
I need to solve a groping problem in my xsl; I have to group the input xml based on , and . If any of these data is not same then create new tag and copy the respective inside that. If you check my xslt i am able to do the grouping by but not sure how to incorporate the same logic for and . I am not sure if i explained the problem very well but if u see the "needed output" section it would be more easy to understand what I want. Thanks in advance for your help.
Input:
<?xml version="1.0" encoding="UTF-8"?>
<BC>
<SO>
<plantCode>xyz</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>UK</airportofunloading>
<package>1</package>
....
</SO>
<SO>
<plantCode>xyz</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>UK</airportofunloading>
<package>2</package>
...
</SO>
<SO>
<plantCode>abc</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>UK</airportofunloading>
<package>5</package>
....
</SO>
<SO>
<plantCode>abc</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>AB</airportofunloading>
<package>1</package>
....
</SO>
</BC>
Needed Output:
<?xml version="1.0" encoding="UTF-8"?>
<BC>
<plant name="xyz">
<SO>
<plantCode>xyz</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>UK</airportofunloading>
<package>1</package>
....
</SO>
<SO>
<plantCode>xyz</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>UK</airportofunloading>
<package>2</package>
....
</SO>
</plant>
<plant name="abc">
<SO>
<plantCode>abc</plantCode>
<airportofloading>US</airportofloading>
<airportofunloading>UK</airportofunloading>
<package>5</package>
....
</SO>
</plant>
<plant name="abc">
<SO>
<plantCode>abc</plantCode开发者_C百科>
<airportofloading>US</airportofloading>
<airportofunloading>AB</airportofunloading>
<package>1</package>
....
</SO>
</plant>
</BC>
My XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml"/>
<xsl:key name="Code" match="SO" use="plantCode"/>
<xsl:template match="BC">
<xsl:element name="BC">
<xsl:apply-templates select="SO[generate-id(.) = generate-id(key ('Code', plantCode)[1])]"/>
</xsl:element>
</xsl:template>
<xsl:template match="SO">
<xsl:element name="plant">
<xsl:attribute name="name"><xsl:value-of select="plantCode"/></xsl:attribute>
<xsl:for-each select="key('Code', plantCode)">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Edit: Sorry, I see now I misunderstood your question. I belive the following is more or less what you are looking for:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="code" match="SO" use="plantCode" />
<xsl:key name="airports" match="SO" use="concat(airportofloading,' ',airportofunloading)" />
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="BC">
<BC>
<xsl:for-each select="SO[generate-id(.)=generate-id(key('code',plantCode))]">
<xsl:variable name="thisCode" select="plantCode"/>
<xsl:for-each select="../SO[generate-id() = generate-id(key('airports', concat(airportofloading,' ',airportofunloading))[plantCode = $thisCode][1])]">
<xsl:element name="plant">
<xsl:attribute name="name">
<xsl:value-of select="plantCode"/>
</xsl:attribute>
<xsl:for-each select="key('airports', concat(airportofloading,' ',airportofunloading))[plantCode = $thisCode]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</BC>
</xsl:template>
That should create one <plant> element for every triple of {plantcode, airportofloading, airportofunloading}. Said <plant> element containing all the <SO> elements for that triple. I believe that is what you wanted, or is very close to it, so you should be able to make any needed adjustments.
精彩评论