[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: XML to XML
Wow Wendell, Thank you so much for your solution as well as your explanation. It worked great. Thanks everyone! Jim Han -----Original Message----- From: Wendell Piez [mailto:wapiez@xxxxxxxxxxxxxxxx] Sent: Wednesday, March 26, 2003 4:48 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: XML to XML Jim, Your problem is actually subtler than you may think it is. This isn't just a matter of having multiple templates; it's that you are faced with an "upconversion", which is to say you want to take advantage of information that is only implicit in your source (in the values of nodes, specifically your <Code> elements), and making it explicit in the node structure of your output. In your case, the implicit information in the source is which category goes inside which. You are going from a flat structure to a nested, hierarchical one. Like many upconversions, it's essentially a grouping problem. Where possible, this kind of "levitation" (getting structure where there was none) is best solved (in my experience) with keys, which are designed to let you retrieve nodes based on associated values. Here, there are two bits of information that are critical. One, to which level should a category be assigned: this is indicated by the string length of its Code child. Two, which category of the next level up does it belong with: this is indicated by the value of the first n-1 characters of the Code, where n is the Code's length. These two bits of logic can be encoded in keys like this: <xsl:key name="level1" match="Category[string-length(Code)=1]" use="'all'"/> (This one is a convenience. It gets all the Categories A, B, C etc., as long as their Code has one character. It returns them all with the key value of 'all'.) <xsl:key name="level2" match="Category[string-length(Code)=2]" use="substring(Code, 1, 1)"/> This one matches Categories AA, AB, DZ, FF etc, keying them to the values A (for AA and AB), D, F etc. <xsl:key name="level3" match="Category[string-length(Code)=3]" use="substring(Code, 1, 2)"/> Same, but matches AAA, AAC, DZC, FFF etc., keying them to AA, DZ, FF etc. Then, <xsl:template match="/"> <Categories> <xsl:apply-templates select="key('level1','all')"/> </Categories> </xsl:template> <xsl:template match="Category[string-length(Code)=1]"> <!-- matches only level 1 nodes --> <LevelOneCategory Code="{Code}" Description="{Description}"> <xsl:apply-templates select="key('level2',Code)"/> <!-- goes and gets the level 2 categories keyed to the value of this one's Code --> </LevelOneCategory> </xsl:template> <xsl:template match="Category[string-length(Code)=2]"> <!-- matches level 2 nodes --> <LevelTwoCategory Code="{Code}" Description="{Description}"> <xsl:apply-templates select="key('level3',Code)"/> <!-- goes and gets the level 3 categories keyed to the value of this one's Code --> </LevelTwoCategory> </xsl:template> <xsl:template match="Category[string-length(Code)=3]"> <!-- matches level 3 nodes --> <LevelThreeCategory Code="{Code}" Description="{Description}"/> </xsl:template> Note that this method will be fast and efficient, but it requires you to know in advance how deep your categories go (how many levels to allow for). If this cannot be known until runtime, you have to use another technique (and it'll be slower). I hope that helps, Wendell At 03:25 PM 3/26/2003, you wrote: >Original: ><Categories> > <Category> > <Code>A</Code> > <Description>Airplanes</Description> > </Category> > <Category> > <Code>AA</Code> > <Description>Airplanes (ARF)</Description> > </Category> > <Category> > <Code>AAE</Code> > <Description>Airplanes (ARF), Electric</Description> > </Category> > <Category> > <Code>AAG</Code> > <Description>Airplanes (ARF), Giant</Description> > </Category> > <Category> > <Code>AAP</Code> > <Description>Airplanes (ARF), Sailplane</Description> > </Category> > <Category> > <Code>B</Code> > <Description>Boats</Description> > </Category> > <Category> > <Code>BA</Code> > <Description>Boats (ARF)</Description> > </Category> > <Category> > <Code>BAE</Code> > <Description>Boats (ARF), Electric</Description> > </Category> ><Categories> > > >Final Result - where one letter, two letter, and three letter categories are >nested. > > ><Categories> > <LevelOneCategory Code="A" Description="Airplanes"> > <LevelTwoCategory Code="AA" Description="Airplanes (ARF)"> > <LevelThreeCategory Code="AAE" >Description="Airplanes (ARF), Electric"/> > <LevelThreeCategory Code="AAG" >Description="Airplanes (ARF), Giant"/> > <LevelThreeCategory Code="AAP" >Description="Airplanes (ARF), Sailplane"/> > </LevelTwoCategory> > </LevelOneCategory> > <LevelOneCategory Code="B" Description="Boats"> > <LevelTwoCategory Code="BA" Description="Boats (ARF)"> > <LevelThreeCategory Code="BAE" Description="Boats >(ARF), Electric"/> > </LevelTwoCategory> > </LevelOneCategory> ><Categories> ====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ====================================================================== XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|