Subject: [xsl] Identity Transform Grouping Question From: <ethan.kalfus@xxxxxxx> Date: Wed, 13 Oct 2004 11:44:46 -0400 |
I have an identity transform that attempts to group elements at a deeply nested level, but I am having trouble accomplishing this. The xslt performs the identity transform and sorts the result tree on a few levels, all successfully. The problem occurs when I attempt the deep-level grouping. Given the following source tree sample: <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="offices.xsl" ?> <locations version="1.0"> <divisions> <division id="B"> <regions> <region name="europe"> <countries> <country name="England"> <offices> <office id="BR4"> <names> <name lang='en'>Branch 4</name> </names> <address> <line>26 Abbey Lane</line> <line>London</line> </address> <cities> <city>London</city> </cities> <phone>+44-22-2222 2222</phone> </office> <office id="BR5"> <names> <name lang='en'>AAAAA Branch 4</name> </names> <address> <line>7 Kings Highway</line> <line>London</line> </address> <cities> <city>London</city> </cities> <phone>+44-99-9999 9999</phone> </office> <office id="BR6"> <names> <name lang='en'>Branch 4</name> </names> <address> <line>22 Abbey Lane</line> <line>London</line> </address> <cities> <city>London</city> </cities> <phone>+44-55-555 5555</phone> </office> </offices> </country> </countries> </region> </regions> </division> </divisions> </locations> ...the xslt should produce the following result tree: <?xml version="1.0" encoding="UTF-8"?> <locations> <divisions> <division id="B"> <regions> <region name="europe"> <countries> <country name="England"> <cities> <city> <name>London</name> <offices> <office> <names> <name lang='en'>AAAAA Branch 4</name> </names> <location> <address> <line>7 Kings Highway</line> <line>London</line> </address> <phone>+44-99-9999 9999</phone> </location> </office> <office> <names> <name lang='en'>Branch 4</name> </names> <location> <address> <line>22 Abbey Lane</line> <line>London</line> </address> <phone>+44-55-555 5555</phone> </location> <location> <address> <line>26 Abbey Lane</line> <line>London</line> </address> <phone>+44-22-2222 2222</phone> </location> </office> </offices> </city> </cities> </country> </countries> </region> </regions> </division> </divisions> </locations> The <office> elements contain all child elements where the office/names/name[@lang='en'] values match. Further, a new element -- <location> has been added as a child to <office>. The goal is to have only one <names> element under an <office> element for each unique occurrence of names/name where @lang='en' -- in other words, group all office locations by their common English office name, then copy all location-specific information for each office to the result tree as new <location> elements underneath the <office> element. My current XSLT is as follows: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:key name="by-city" match="temp/office/cities/city" use="."/> <xsl:template match="/"> <locations> <divisions> <xsl:for-each select="locations/divisions/division"> <xsl:sort select="@id"/> <division id="{@id}"> <regions> <xsl:for-each select="regions/region"> <xsl:sort select="@name"/> <region name="{@name}"> <countries> <xsl:for-each select="countries/country"> <xsl:sort select="@name"/> <country name="{@name}"> <xsl:variable name="rtf"> <temp> <xsl:copy-of select="offices/office"/> </temp> </xsl:variable> <xsl:for-each select="msxsl:node-set($rtf)/temp/office/cities/city[generate-id(.) = generate-id(key('by-city', .)[1])]"> <xsl:sort select="."/> <cities> <city> <name> <xsl:value-of select="."/> </name> <offices> <xsl:for-each select="key('by-city', .)"> <xsl:sort select="../../names/name[@lang='en']"/> <xsl:sort select="../../address"/> <xsl:if test="../../names/name[@lang='en'] !=../../preceding-sibling::names/name[@lang='en']"> <!-- <office> new <office> element should be inserted here --> <xsl:copy-of select="../../names"/> </xsl:if> <location> <xsl:copy-of select="../preceding-sibling::address"/> <xsl:copy-of select="../following-sibling::phone"/> </location> <!-- </office> if the current node is the last in a group with the same /names/name[@lang='en'] value, then closing tag should be inserted here --> </xsl:for-each> </offices> </city> </cities> </xsl:for-each> </country> </xsl:for-each> </countries> </region> </xsl:for-each> </regions> </division> </xsl:for-each> </divisions> </locations> </xsl:template> </xsl:stylesheet> ...and my result tree looks like this: <?xml version="1.0" encoding="UTF-8"?> <locations> <divisions> <division id="B"> <regions> <region name="europe"> <countries> <country name="England"> <cities> <city> <name>London</name> <offices> <location> <address> <line>7 Kings Highway</line> <line>London</line> </address> <phone>+44-99-9999 9999</phone> </location> <location> <address> <line>22 Abbey Lane</line> <line>London</line> </address> <phone>+44-55-555 5555</phone> </location> <location> <address> <line>26 Abbey Lane</line> <line>London</line> </address> <phone>+44-22-2222 2222</phone> </location> </offices> </city> </cities> </country> </countries> </region> </regions> </division> </divisions> </locations> The missing pieces are unique <names> elements (selected according to the above-specified criteria) and the appropriate placement of <office> elements (encapsulating <names> and <location> elements). I appreciate any help that can be offered! Visit our website at http://www.ubs.com This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required please request a hard-copy version. This message is provided for informational purposes and should not be construed as a solicitation or offer to buy or sell any securities or related financial instruments.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Problem using Position() , Michael Kay | Thread | Re: [xsl] Identity Transform Groupi, David Carlisle |
Re: [xsl] support extension in xala, Werner, Wolfgang | Date | RE: [xsl] Problem using Position() , Pieter Reint Siegers |
Month |