Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
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 software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old November 4th, 2003, 01:55 PM
Authorized User
 
Join Date: Nov 2003
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
 
Old November 5th, 2003, 03:50 AM
Friend of Wrox
 
Join Date: Jun 2003
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
 
Old November 5th, 2003, 02:57 PM
Authorized User
 
Join Date: Oct 2003
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

 
Old November 5th, 2003, 04:14 PM
Authorized User
 
Join Date: Nov 2003
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.






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





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