Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
| FAQ | Members List | Search | Today's Posts | Mark Forums Read
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old November 4th, 2003, 01:55 PM
Authorized User
 
Join Date: Nov 2003
Location: , , .
Posts: 16
Thanks: 0
Thanked 0 Times in 0 Posts
Default A Challenge...

How do you transform this:
Code:
<root>
   <folder label="Educational tools" level="1">Educational tools</folder>
   <folder label="Online Books" level="2">Online Books</folder>
   <folder label="Ebooks" level="3">Online Books</folder>
   <folder label="Reference Sites" level="2">Reference Sites</folder>
   <folder label="Textbooks" level="1">Textbooks</folder>
   <folder label="Trochim" level="2" >Trochim</folder>
</root>
To this:

Code:
<node label="Educational tools">
   <node label="Online Books">
      <node label="Ebooks"></node>
   </node>
   <node label="Reference Sites"></node>
</node>
<node label="Textbooks">
   <node label="Trochim"></node>
</node>
Note that the Level is what determines the depth of a node, it is assumed that the original XML is in order, so a Level 2 node appearing after a Level 1 node is assumed to be a child of it. Let me know if more clarification is needed.

-Aaron
Reply With Quote
  #2 (permalink)  
Old November 5th, 2003, 03:50 AM
Friend of Wrox
 
Join Date: Jun 2003
Location: Nor Hachin, Kotayk, Armenia.
Posts: 147
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to armmarti
Default

Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="/root/folder[@level=1]"/>
        </root>    
    </xsl:template>

    <xsl:template match="folder">
        <xsl:variable name="l" select="@level"/>
        <xsl:variable name="all-children" select="current()/following-sibling::*[@level = $l + 1][count(preceding-sibling::*[@level = $l][1] | current()) = 1]"/>
        <node>
            <xsl:copy-of select="@label"/>
            <xsl:apply-templates select="$all-children"/>
        </node>
    </xsl:template>
</xsl:stylesheet>
Regards,
Armen
Reply With Quote
  #3 (permalink)  
Old November 5th, 2003, 02:57 PM
Authorized User
 
Join Date: Oct 2003
Location: , PA, USA.
Posts: 22
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Although Armen's solution definitely works, I just wanted to point out that if you come across these kinds of "unflattening" problems in the future, you might want to look into grouping techniques (see http://www.jenitennison.com/xslt/grouping or look under "Grouping" in the XSLT Programmer's Reference).

FYI -- a solution to a very similar problem was provided by Mr. Kay in the July 2002 archives under "Unflatten XML using XSLT". By slightly modifying his solution you can use:

<xsl:template match="root">
  <xsl:apply-templates select="folder[@level=1]"/>
</xsl:template>

<xsl:template match="folder">

  <node>
    <xsl:copy-of select="@label"/>
    <xsl:apply-templates select="following-sibling::*[@level=current()/@level+1][generate-id(current()) = generate-id(preceding-sibling::*[@level=current()/@level][1])]"/>
  </node>

</xsl:template>

and his explanation: "What this means is: process the following siblings of this element that have an @level that is one greater than the @level of this element, provided that the most recent preceding sibling of that element at the same level as the current element is the current element.

...sam

Reply With Quote
  #4 (permalink)  
Old November 5th, 2003, 04:14 PM
Authorized User
 
Join Date: Nov 2003
Location: , , .
Posts: 16
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Amazing! My boss and I had been trying to figure this one out for a day and a half. This is somewhat close to what we were trying, but much more elegant and efficient. Thank you both (armmarti and shbyland) for lending your expertise.

Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
A little challenge... chacquard Access VBA 7 February 2nd, 2007 11:38 AM
query challenge alexxx Access 5 October 31st, 2006 03:34 PM
Memobox Challenge rocknrisk Access 8 July 30th, 2005 02:36 AM
Fancy a challenge that would really help me out? Brettvan1 VB.NET 2002/2003 Basics 2 June 2nd, 2005 09:42 AM
Challenge.... developerz BOOK: ASP.NET Website Programming Problem-Design-Solution 2 September 29th, 2003 04:49 PM



All times are GMT -4. The time now is 05:45 AM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.