Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


RE: Re-organize and sort source tree

From: anyware@-----------.---------.---
To: NULL
Date: 10/11/2004 1:55:00 PM
Hello Mukul:

   I have a further question, if I may.

   I would like to alter the xsl you have supplied so that I can further 
"group" certain child elements.  Following my previous posted xml sample, if 
within a specific city I have multiple <office> elements and some of these 
elements have the same value for the <name> child, then I want to copy just 
the first occurrence of the <name> element, followed by all the <address> 
siblings for that unique office name.  So, the following fragment is a 
modified version from the original xml I had posted:

<country name="China">
   <offices>
      <office id="BR6">
         <names>
            <name lang='en'>First Bank</name>
            <name lang='ch'>第一家银行</name>
         </names>
         <address>
               <line>China World Tower 2</line>
               <line>2 Jian Guo Men Wai Avenue</line>
               <line>Beijing</line>
         </address>
         <cities>
            <city>Beijing</city>
         </cities>
         <phone>435345345</phone>
      </office>
      <office id="BR5">
         <names>
            <name lang='en'>First Bank</name>
            <name lang='ch'>第一家银行</name>
         </names>
         <address>
               <line>China World Tower 1</line>
               <line>1 Jian Guo Men Wai Avenue</line>
               <line>Beijing</line>
         </address>
         <cities>
            <city>Beijing</city>
         </cities>
         <phone>888888888</phone>
      </office>
   </offices>
</country>

   The office name is localized, so there can multiple versions of the same 
value, each in a different language.  Because of this, there are 4 
significant differences:
1.  The <name> element has been encapsulated by a new <names> parent 
element, and 
2.  The <name> element has a new attribute - "lang" - to denote the relevant 
language for the localized value.
3.  All of the locations with the same office name are grouped under a new 
<locations> parent element, with each location's relevant child elements 
encapsulated by a <location> element.
4.  The "id" attribute on the <office> element is no longer required in the 
result tree.

   I would like the transformed xml to maintain the ordering I originally 
specified, but add the new grouping.  The algorithm can assume that there 
will always be an English version of the <name> element (e.g. lang='en') to 
use for the grouping.

   If possible, I would also like to extend the sort to the address/line 
elements, so that all addresses for a particular office are sorted.

The result tree would look like the following:

<country name="China">
    <cities>
       <city>
          <name>Beijing</name>
          <offices>
             <office>
                <names>
                   <name lang='en'>First Bank</name>
                   <name lang='ch'>第一家银行</name>
                </names>
                <locations>
                   <location>
                      <address>
                         <line>China World Tower 1</line>
                         <line>1 Jian Guo Men Wai Avenue</line>
                      </address>
                      <phone>888888888</phone>
                   </location>
                   <location>
                      <address>
                         <line>China World Tower 2</line>
                         <line>2 Jian Guo Men Wai Avenue</line>
                      </address>
                      <phone>435345345</phone>
                   </location>
                </locations>
             </office>
          </offices>
       </city>
    </cities>
 </country>

   Thank you again for any help you can offer!

"anyware" wrote:

> Mukul,
> 
>    I had managed to get that working myself (!).  Thanks very much for your 
> help; your solution works perfectly and is quite efficient.  I appreciate 
> your assistance.
> 
> "Mukul Gandhi" wrote:
> 
> > Please apply this correction -
> > 
> > <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="../../name" />
> > 	       <office id="{../../@id}">
> >                            <xsl:copy-of select="../preceding-sibling::name" />
> >                            <xsl:copy-of 
> > select="../preceding-sibling::address" />
> >                            <xsl:copy-of select="../following-sibling::phone" 
> > />
> >                        </office>
> > 	     </xsl:for-each>
> > 	  </offices>
> >               </city>
> >            </cities>
> >         </xsl:for-each>
> > 
> > I am applying Muenchian grouping to every offices node. For this reason, I 
> > had to convert this variable <xsl:variable name="rtf"> (short for Result Tree 
> > Fragment) into a node-set. 
> > 
> > To learn Muenchian grouping, please read here 
> > http://www.jenitennison.com/xslt/grouping/index.html .
> > 
> > Regards,
> > Mukul
> > 
> > "anyware" wrote:
> > 
> > > Hi Mukul:
> > > 
> > >    First, thanks very much for the reply and solution.
> > > 
> > >    It is almost perfect, just one flaw that I see.  The <city> element is 
> > > meant to encapsulate the <offices> element, but is instead appearing as its 
> > > sibling.  So, the xslt produces this fragment:
> > > 
> > >    <country name="Canada">
> > >       <cities>
> > >          <city>
> > >             <name>Calgary</name>
> > >          </city>
> > >          <offices>
> > >             <office id="Branch 2">
> > >                <name>Canadian Branch</name>
> > >                <address>
> > >                   <line>1 Prince Edward Boulevard</line>
> > >                   <line>5th Floor</line>
> > >                   <line>Room 10</line>
> > >                   <line>Calgary, Alberta</line>
> > >                </address>
> > >                <phone>(888) 888-8888</phone>
> > >             </office>
> > >          </offices>
> > >       </cities>
> > > 
> > > But what it should produce is:
> > > 
> > >     <country name="Canada">
> > >       <cities>
> > >          <city>
> > >             <name>Calgary</name>
> > >             <offices>
> > >                <office id="Branch 2">
> > >                   <name>Canadian Branch</name>
> > >                   <address>
> > >                      <line>1 Prince Edward Boulevard</line>
> > >                      <line>5th Floor</line>
> > >                      <line>Room 10</line>
> > >                      <line>Calgary, Alberta</line>
> > >                   </address>
> > >                   <phone>(888) 888-8888</phone>
> > >                </office>
> > >             </offices>
> > >          </city>
> > >       </cities>
> > >    </country>
> > >  
> > > Also, I have seen similar usage of the Muenchian method that you are 
> > > employing, but am having trouble understanding how it works.  I can't figure 
> > > out how the unique list of city keys is generated (i.e. how does 
> > > generate-id() work?) and how the equality check 
> > > (genrate-id(.)=generate-id(key)'by-city',.)) work?  Would you mind explaining 
> > > the following statement:
> > > 
> > >  <xsl:for-each  
> > > select="msxsl:node-set($rtf)/temp/office/cities/city[generate-id(.) = 
> > >  generate-id(key('by-city', .)[1])]">
> > > 
> > > Thanks again for all of your help!
> > > 
> > > 
> > > 
> > > "Mukul Gandhi" wrote:
> > > 
> > > > Please try this XSL -
> > > > 
> > > > <?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>
> > > >                                                 </city>
> > > >                                                 <offices>
> > > > 			<xsl:for-each select="key('by-city', .)">	
> > > > 			   <xsl:sort select="../../name" />
> > > > 			   <office id="{../../@id}">
> > > >                                                       <xsl:copy-of 
> > > > select="../preceding-sibling::name" />
> > > >                                                       <xsl:copy-of 
> > > > select="../preceding-sibling::address" />
> > > >                                                       <xsl:copy-of 
> > > > select="../following-sibling::phone" />
> > > >                                                    </office>
> > > > 		       </xsl:for-each>						   </offices>
> > > > 	                </cities>
> > > > 	             </xsl:for-each>
> > > > 	          </country>
> > > > 	      </xsl:for-each>
> > > > 	</countries>
> > > >              </region>
> > > >           </xsl:for-each>
> > > >        </regions>
> > > >     </division>
> > > >    </xsl:for-each>
> > > >   </divisions>
> > > > </locations>
> > > > </xsl:template>
> > > > 
> > > > </xsl:stylesheet>
> > > > 
> > > > Regards,
> > > > Mukul
> > > > 
> > > > "anyware" wrote:
> > > > 
> > > > >    I'm struggling with using the Muenchian method to produce a result tree 
> > > > > that re-organizes and sorts the 
> > > > > source tree's nodes.
> > > > >    
> > > > >    The goal is to take the source tree and produce a result set that makes 
> > > > > the 
> > > > > child <cities> element (including its child <city> element) a parent of the 
> > > > > <offices> element.  The result tree would also be sorted by the following 
> > > > > ascending order:
> > > > > division/@id, region/@name, country/@name, new cities/city/name location 
> > > > > path, and office/name.
> > > > > 
> > > > >    I appreciate any assistance with the XSLT.  Also, if possible, please 
> > > > > include comments describing how the
> > > > > XSLT works.  Thanks very much!
> > > > > 
> > > > > Given the following source tree...
> > > > > 
> > > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > > <locations>
> > > > >    <divisions>
> > > > >       <division id="B">
> > > > >          <regions>
> > > > >             <region name="pacific">
> > > > >                <countries>
> > > > >                   <country name="China">
> > > > >                      <offices>
> > > > >                         <office id="BR5">
> > > > >                            <name>Branch 5</name>
> > > > >                            <address>
> > > > >                                  <line>China World Tower 1</line>
> > > > >                                  <line>1 Jian Guo Men Wai Avenue</line>
> > > > >                                  <line>Beijing</line>
> > > > >                            </address>
> > > > >                            <cities>
> > > > >                               <city>Beijing</city>
> > > > >                            </cities>
> > > > >                            <phone></phone>
> > > > >                         </office>
> > > > >                      </offices>
> > > > >                   </country>
> > > > >                </countries>
> > > > >             </region>
> > > > >          </regions>
> > > > >       </division>
> > > > >       <division id="A">
> > > > >          <regions>
> > > > >             <region name="europe">
> > > > >                <countries>
> > > > >                   <country name="Germany">
> > > > >                      <offices>
> > > > >                         <office id="BR3">
> > > > >                            <name>Branch 3</name>
> > > > >                            <address>
> > > > >                                  <line>P.O. Box 1210</line>
> > > > >                                  <line>Frankfurt, Germany</line>
> > > > >                            </address>
> > > > >                            <cities>
> > > > >                               <city>Frankfurt</city>
> > > > >                            </cities>
> > > > >                            <phone>+49-55-5555 5555</phone>
> > > > >                         </office>
> > > > >                      </offices>
> > > > >                   </country>
> > > > >                   <country name="England">
> > > > >                      <offices>
> > > > >                         <office id="BR4">
> > > > >                            <name>Branch 4</name>
> > > > >                            <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">
> > > > >                            <name>AAAAA Branch 4</name>
> > > > >                            <address>
> > > > >                                  <line>7 Kings Highway</line>
> > > > >                                  <line>London</line>
> > > > >                            </address>
> > > > >                            <cities>
> > > > >                               <city>London</city>
> > > > >                            </cities>
> > > > >                            <phone>+44-99-9999 9999</phone>
> > > > >                         </office>
> > > > >                      </offices>
> > > > >                   </country>
> > > > >                </countries>
> > > > >             </region>
> > > > >             <region name="americas">
> > > > >                <countries>
> > > > >                   <country name="United States">
> > > > >                      <offices>
> > > > >                         <office id="HO">
> > > > >                            <name>Home Office</name>
> > > > >                            <address>
> > > > >                                  <line>P.O. Box 1234</line>
> > > > >                                  <line>New York, NY  11111</line>
> > > > >                            </address>
> > > > >                            <cities>
> > > > >                               <city>New York</city>
> > > > >                            </cities>
> > > > >                            <phone>(212) 123-4567</phone>
> > > > >                         </office>
> > > > >                         <office id="BR1">
> > > > >                            <name>Branch 1</name>
> > > > >                            <address>
> > > > >                                  <line>999 Main Street</line>
> > > > >                                  <line>Suite 1200</line>
> > > > >                                  <line>Miami, FL  22222</line>
> > > > >                            </address>
> > > > >                            <cities>
> > > > >                               <city>Miami</city>
> > > > >                            </cities>
> > > > >                            <phone>777-7777</phone>
> > > > >                         </office>
> > > > >                      </offices>
> > > > >                   </country>
> > > > >                   <country name="Canada">
> > > > >                      <offices>
> > > > >                         <office id="Branch 2">
> > > > >                            <name>Canadian Branch</name>
> > > > >                            <address>
> > > > >                                  <line>1 Prince Edward Boulevard</line>
> > > > >                                  <line>5th Floor</line>
> > > > >                                  <line>Room 10</line>
> > > > >                                  <line>Calgary, Alberta</line>
> > > > >                            </address>
> > > > >                            <cities>
> > > > >                               <city>Calgary</city>
> > > > >                            </cities>
> > > > >                            <phone>(888) 888-8888</phone>
> > > > >                         </office>
> > > > >                      </offices>
> > > > >                   </country>
> > > > >                </countries>
> > > > >             </region>
> > > > >          </regions>
> > > > >       </division>
> > > > >    </divisions>
> > > > > </locations>
> > > > > 
> > > > > 
> > > > > ...the XSLT would generate the following result tree:
> > > > > 
> > > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > > <locations>
> > > > >    <divisions>
> > > > >       <division id="A">
> > > > >          <regions>
> > > > >             <region name="americas">
> > > > >                <countries>
> > > > >                   <country name="Canada">
> > > > >                      <cities>
> > > > >                         <city>
> > > > >                            <name>Calgary</name>
> > > > >                            <offices>
> > > > >                               <office id="Branch 2">
> > > > >                                  <name>Canadian Branch</name>
> > > > >                                  <address>
> > > > >                                        <line>1 Prince Edward Boulevard</line>
> > > > >                                        <line>5th Floor</line>
> > > > >                                        <line>Room 10</line>
> > > > >                                        <line>Calgary, Alberta</line>
> > > > >                                  </address>
> > > > >                                  <phone>(888) 888-8888</phone>
> > > > >                               </office>
> > > > >                            </offices>
> > > > >                         </city>
> > > > >                      </cities>
> > > > >                   </country>
> > > > >                   <country name="United States">
> > > > >                      <cities>
> > > > >                         <city>
> > > > >                            <name>Miami</name>
> > > > >                            <offices>
> > > > >                               <office id="BR1">
> > > > >                                  <name>Branch 1</name>
> > > > >                                  <address>
> > > > >                                        <line>999 Main Street</line>
> > > > >                                        <line>Suite 1200</line>
> > > > >                                        <line>Miami, FL  22222</line>
> > > > >                                  </address>
> > > > >                                  <phone>777-7777</phone>
> > > > >                               </office>
> > > > >                            </offices>
> > > > >                         </city>
> > > > >                         <city>
> > > > >                            <name>New York</name>
> > > > >                            <offices>
> > > > >                               <office id="HO">
> > > > >                                  <name>Home Office</name>
> > > > >                                  <address>
> > > > >                                        <line>P.O. Box 1234</line>
> > > > >                                        <line>New York, NY  11111</line>
> > > > >                                  </address>
> > > > >                                  <phone>(212) 123-4567</phone>
> > > > >                               </office>
> > > > >                            </offices>
> > > > >                         </city>
> > > > >                      </cities>
> > > > >                   </country>
> > > > >                </countries>
> > > > >             </region>
> > > > >             <region name="europe">
> > > > >                <countries>
> > > > >                   <country name="England">
> > > > >                      <cities>
> > > > >                         <city>
> > > > >                            <name>London</name>
> > > > >                            <offices>
> > > > >                               <office id="BR5">
> > > > >                                  <name>AAAAA Branch 5</name>
> > > > >                                  <address>
> > > > >                                        <line>7 Kings Highway</line>
> > > > >                                        <line>London</line>
> > > > >                                  </address>
> > > > >                                  <phone>+44-99-9999 9999</phone>
> > > > >                               </office>
> > > > >                               <office id="BR4">
> > > > >                                  <name>Branch 4</name>
> > > > >                                  <address>
> > > > >                                        <line>26 Abbey Lane</line>
> > > > >                                        <line>London</line>
> > > > >                                  </address>
> > > > >                                  <phone>+44-22-2222 2222</phone>
> > > > >                               </office>
> > > > >                            </offices>
> > > > >                         </city>
> > > > >                      </cities>
> > > > >                   </country>
> > > > >                   <country name="Germany">
> > > > >                      <cities>
> > > > >                         <city>
> > > > >                            <name>Frankfurt</name>
> > > > >                            <offices>
> > > > >                               <office id="BR3">
> > > > >                                  <name>Branch 3</name>
> > > > >                                  <address>
> > > > >                                        <line>P.O. Box 1210</line>
> > > > >                                        <line>Frankfurt, Germany</line>
> > > > >                                  </address>
> > > > >                                  <phone>+49-55-5555 5555</phone>
> > > > >                               </office>
> > > > >                            </offices>
> > > > >                         </city>
> > > > >                      </cities>
> > > > >                   </country>
> > > > >                </countries>
> > > > >             </region>
> > > > >          </regions>
> > > > >       </division>
> > > > >       <division id="B">
> > > > >          <regions>
> > > > >             <region name="pacific">
> > > > >                <countries>
> > > > >                   <country name="China">
> > > > >                      <cities>
> > > > >                         <city>
> > > > >                            <name>Beijing</name>
> > > > >                            <offices>
> > > > >                               <office id="BR5">
> > > > >                                  <name>Branch 5</name>
> > > > >                                  <address>
> > > > >                                        <line>China World Tower 1</line>
> > > > >                                        <line>1 Jian Guo Men Wai Avenue</line>
> > > > >                                        <line></line>
> > > > >                                  </address>
> > > > >                                  <phone></phone>
> > > > >                               </office>
> > > > >                            </offices>
> > > > >                         </city>
> > > > >                      </cities>
> > > > >                   </country>
> > > > >                </countries>
> > > > >             </region>
> > > > >          </regions>
> > > > >       </division>
> > > > >    </divisions>
> > > > > </locations>
> > > > > 


transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent