[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Identity Transform Grouping Question

Subject: Identity Transform Grouping Question
From: <ethan.kalfus@xxxxxxx>
Date: Wed, 13 Oct 2004 11:44:46 -0400
identity transform
   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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.