473,391 Members | 1,452 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,391 software developers and data experts.

Interesting XML traversing problem

I've been struggling too long with this problem and will revere anyone as a god if they can figure it out.

I have this xml:
Expand|Select|Wrap|Line Numbers
  1. <tasks>
  2.      <task id="t1"/>
  3.      <task id="t2">
  4.           <folderid>one</folderid>
  5.      </task>
  6.      <task id="t3">
  7.           <note>just some content here</note>
  8.           <folderid>two</folderid>
  9.      </task>
  10.      <task id="t4">
  11.           <folderid>two</folderid>
  12.           <folderid>three</folderid>
  13.           <folderid>four</folderid>
  14.      </task>
  15.      <task id="t5">
  16.           <folderid>four</folderid>
  17.      </task>
  18.      <task id="t6"/>
  19.           <note>blah blah blah</note>
  20.      </task>
  21.      <task id="t7"/>
  22. </tasks>
  23.  
And I want this result html:
Expand|Select|Wrap|Line Numbers
  1. <div id="root">
  2.      task t1
  3.      task t6 - blah blah blah
  4.      task t7
  5. </div>
  6. <div id="one">
  7.      task t2
  8. </div>
  9. <div id="two">
  10.      task t3 - just some content here
  11.      task t4
  12. </div>
  13. <div id="three">
  14.      task t4
  15. </div>
  16. <div id="four">
  17.      task t4
  18.      task t5
  19. </div>
  20.  
- each task may have 0 to many "folderid" elements
- each folder id will have it's own div
- each div section will list those tasks that have that folderid
- if a task has no folderid sibling, it is put into the "root" div
- each task can only have one note child element
Oct 14 '08 #1
8 1743
Dormilich
8,658 Expert Mod 8TB
- each task may have 0 to many "folderid" elements
- each folder id will have it's own div
- each div section will list those tasks that have that folderid
- if a task has no folderid sibling, it is put into the "root" div
- each task can only have one note child element
problem 1: your xml is not well-formed (missing root element and xml declaration)
problem 2: please use code tags [code] when posting code

the last requirement will need a DTD or similar for validation (though you could catch such an exception)

the most complicated thing is to get the <div>s right. my proposal - get all <folderid>s (<xsl:for-each>), sort them (<xsl:sort>) and create a new <div> when the content changes.

if you show me what you've done so far, I will gladly re- and advise you.

regards
Oct 14 '08 #2
jkmyoung
2,057 Expert 2GB
Tasks without folder children:
task/[not(folderid)]

Assuming you're using XSLT 1.0 and you have a task template already:
to get the other tasks, you'll probably use something like Muenchian Grouping:
http://www.jenitennison.com/xslt/gro...muenchian.html

Expand|Select|Wrap|Line Numbers
  1. <div id="root">
  2.   <xsl:apply-templates select="task/[not(folderid)]"/>
  3.   <xsl:for-each select="//folderid[not(current() = preceding::folderid]">
  4.   <!-- now you have unique folderids -->
  5.     <div id="{.}">
  6.       <xsl:apply-templates select="//folderid[current() = .]/.."/>
  7.        <!-- get parent task node -->
  8.     </div>
  9.   </xsl:for-each>
  10. </div>
  11.  
Oct 14 '08 #3
Sorry it took so long to get reply. Been a long day at work.

I left the root element and xml declaration out by mistake. I thought it would be easier to ask for help by dummying down the XML. In order to show what I've done so far, I'll post the code as-is.

My XML:
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <?xml-stylesheet type="text/xsl" href="..\myxsl.xsl"?>
  3. <root version="3">
  4.     <context>
  5.         <folders>
  6.             <folder id="970f67719995f688" name="Inbox" icon="inbox"/>
  7.             <folder id="3a6bd2e5fe4b7b0a" name="Personal" icon="home">
  8.                             <folder id="492e514a76b05a3a" name="Longterm" icon="person"/>
  9.             </folder>
  10.             <folder id="2dab99b095a73877" name="Office" icon="office"/>
  11.             <folder id="734059758a6a0f83" name="Groceries" icon="cart">
  12.                             <folder id="129e2ed6cd372e1f" name="Drinks" icon="cart"/>
  13.                             <folder id="a485f0318e18e0e3" name="Party" icon="music"/>
  14.             </folder>
  15.             <folder id="6c74b7b4eceb796f" name="Very-Important" icon="info"/>
  16.             <folder id="826ceb631b4e7039" name="Web"/>
  17.             <folder id="8c32ad3f8a34db4c" name="XMas"/>
  18.         </folders>
  19.         <tasks>
  20.                 <task id="9cda311cb7351fff" desc="remember the milk"/>
  21.                 <task id="c82f392f4f21dc56" desc="focus on everything"/>
  22.                 <task id="1873b622ff99598f" desc="call Susan">
  23.                                 <folder>3a6bd2e5fe4b7b0a</folder>
  24.                 </task>
  25.                 <task id="0955b7d4fa5b9dfd" desc="research options for participating in north pole expedition">
  26.                                 <note>(before it&apos;'s too late! ;)</note>
  27.                                 <folder>492e514a76b05a3a</folder>
  28.                 </task>
  29.                 <task id="db947856a257c6cf" desc="email Frank (gym thing)">
  30.                                 <folder>970f67719995f688</folder>
  31.                 </task>
  32.                 <task id="4c69ff58577cb622" desc="think about my long-term prospects at ACME">
  33.                                 <folder>2dab99b095a73877</folder>
  34.                 </task>
  35.                 <task id="9699da44e2d7439d" desc="tell Lumbergh what I really think of him">
  36.                                 <folder>2dab99b095a73877</folder>
  37.                 </task>
  38.                 <task id="b0caf9f07c206c69" desc="demolish that HP printer!!!!">
  39.                                 <folder>2dab99b095a73877</folder>
  40.                                 <folder>6c74b7b4eceb796f</folder>
  41.                 </task>
  42.                 <task id="afe68a1c545b9172" desc="buy cheese">
  43.                                 <folder>734059758a6a0f83</folder>
  44.                 </task>
  45.                 <task id="04e9ecce043c46b1" desc="buy spam">
  46.                                 <folder>734059758a6a0f83</folder>
  47.                 </task>
  48.                 <task id="301126e402623bb0" desc="buy lettuce for Susan">
  49.                                 <folder>734059758a6a0f83</folder>
  50.                 </task>
  51.                 <task id="5ab1e5e579a0f7c7" desc="buy this German beer Frank was talking about">
  52.                                 <note>think it was called &quot;"Tannenzäpfle&quot;"</note>
  53.                                 <folder>129e2ed6cd372e1f</folder>
  54.                 </task>
  55.                 <task id="73e4a64f7845856a" desc="buy finger-food">
  56.                                 <folder>a485f0318e18e0e3</folder>
  57.                 </task>
  58.                 <task id="26af69c4e916321e" desc="book flight to Tonga">
  59.                                 <folder>3a6bd2e5fe4b7b0a</folder>
  60.                                 <folder>8c32ad3f8a34db4c</folder>
  61.                 </task>
  62.                 <task id="c43bfd24bd5817af" desc="sign up for lis.to newsletter">
  63.                                 <note>http://lis.to/</note>
  64.                                 <folder>970f67719995f688</folder>
  65.                 </task>
  66.  
  67.             </tasks>
  68.     </context>
  69. </root>
  70.  
My XSL:
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:template match="/root/context">
  4. <html>
  5.     <head>
  6.         <title>My Lists</title>
  7.  
  8.     </head>
  9.     <body>
  10.  
  11.     <!-- build divs -->
  12.  
  13.         <div class="tabs-container">
  14.             <xsl:for-each select="//folders//*">
  15.                 <xsl:call-template name="GetTasksByFolderTest">
  16.                                 <xsl:with-param name="FolderId" select="@id"/>
  17.                 </xsl:call-template>
  18.             </xsl:for-each>
  19.             <!--Below is an example of html div's I want-->
  20.             <!--<div class="tab" id="tab1">
  21.                 <h2>number 1</h2>
  22.                 <p>put some crap here</p>
  23.             </div>
  24.             <div class="tab" id="tab2">
  25.                 <h2>number 2</h2>
  26.                 <p>put some crap here too</p>
  27.             </div>
  28.             <div class="tab" id="tab3">
  29.                 <h2>number 3</h2>
  30.                 <p>and more here for tab 3</p>
  31.             </div>
  32.             <div class="tab" id="tab4">
  33.                 <h2>number 4</h2>
  34.                 <p>and yeah put something here for 4</p>
  35.             </div>
  36.             <div class="tab" id="test">
  37.                 <h2>number test</h2>
  38.                 <p>and yeah put something here for test</p>
  39.             </div>-->
  40.         </div><!-- end divs -->
  41.     </body>
  42. </html>
  43. </xsl:template>
  44.  
  45.  
  46. <xsl:template name="GetTasksByFolderTest">
  47. <xsl:param name="FolderId"/>
  48. <xsl:for-each select="//tasks//*">
  49.     <xsl:choose>
  50.         <xsl:when test="$FolderId = @id">
  51.             <xsl:value-of select="@desc"/>
  52.         </xsl:when>
  53.     </xsl:choose>
  54. </xsl:for-each>
  55.     <div class="tab" id="{$FolderId}">
  56.         <h2>
  57.             <xsl:value-of select="$FolderId"/> | <xsl:value-of select="@id"/>
  58.         </h2>            
  59.     </div>
  60. </xsl:template>
  61. </xsl:stylesheet>
  62.  
I can't really change the XML as it's coming from a third-party.


----------------
problem 1: your xml is not well-formed (missing root element and xml declaration)
problem 2: please use code tags [code] when posting code

the last requirement will need a DTD or similar for validation (though you could catch such an exception)

the most complicated thing is to get the <div>s right. my proposal - get all <folderid>s (<xsl:for-each>), sort them (<xsl:sort>) and create a new <div> when the content changes.

if you show me what you've done so far, I will gladly re- and advise you.

regards
Oct 15 '08 #4
I am playing around with this code but can't quite seem to get it to work.

I put it in my Task template and using Cooktop xml I get the error "Keyword xsl:apply-template may not be used here."

Not being very well versed in XSLT, I find reading this code a bit difficult. :(
I'll keep playing around and see if I can eventually figure out how it works.

Thanks.

-------
Tasks without folder children:
task/[not(folderid)]

Assuming you're using XSLT 1.0 and you have a task template already:
to get the other tasks, you'll probably use something like Muenchian Grouping:
http://www.jenitennison.com/xslt/gro...muenchian.html

Expand|Select|Wrap|Line Numbers
  1. <div id="root">
  2.   <xsl:apply-template select="task/[not(folderid)]"/>
  3.   <xsl:for-each select="//folderid[not(current() = preceding::folderid]">
  4.   <!-- now you have unique folderids -->
  5.     <div id="{.}">
  6.       <xsl:apply-templates select="//folderid[current() = .]/.."/>
  7.        <!-- get parent task node -->
  8.     </div>
  9.   </xsl:for-each>
  10. </div>
  11.  
Oct 15 '08 #5
Dormilich
8,658 Expert Mod 8TB
got some basic code working:
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="ISO-8859-1" ?> 
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3.  
  4. <xsl:output method="html" indent="yes"/>
  5.  
  6. <xsl:template match="/">
  7. <html>
  8. <body>
  9. // I don't know why but apply-templates doesn't get all
  10.     <xsl:for-each select="//folder[@id]">
  11.         <div id="{@id}">
  12.             <xsl:call-template name="xyz"/>
  13.         </div>
  14.     </xsl:for-each>
  15. </body>
  16. </html>
  17. </xsl:template>
  18.  
  19. <xsl:template name="xyz">
  20.     <xsl:variable name="id" select="@id"/>
  21.     <xsl:for-each select="//task[folder = $id]">
  22. task: <xsl:value-of select="@id"/>,
  23. // or whatever code comes here
  24.     </xsl:for-each>
  25. </xsl:template>
  26.  
  27. </xsl:stylesheet>
I skipped the "root" div and the check for the <note> child, but it makes the divs as wanted.

regards

Am I a god now? *gg*
Oct 15 '08 #6
jkmyoung
2,057 Expert 2GB
Accidentally deleted the 's' when posting from apply-templates
Oct 15 '08 #7
Beautiful! Yes, you are a god. Honestly I don't know how some of you XSLT gurus got to where you are. It's a heck of a language to learn.

I added the extra bits of code I needed and got it working exactly as envisioned.

Thank you so much!!!



got some basic code working:
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="ISO-8859-1" ?> 
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3.  
  4. <xsl:output method="html" indent="yes"/>
  5.  
  6. <xsl:template match="/">
  7. <html>
  8. <body>
  9. // I don't know why but apply-templates doesn't get all
  10.     <xsl:for-each select="//folder[@id]">
  11.         <div id="{@id}">
  12.             <xsl:call-template name="xyz"/>
  13.         </div>
  14.     </xsl:for-each>
  15. </body>
  16. </html>
  17. </xsl:template>
  18.  
  19. <xsl:template name="xyz">
  20.     <xsl:variable name="id" select="@id"/>
  21.     <xsl:for-each select="//task[folder = $id]">
  22. task: <xsl:value-of select="@id"/>,
  23. // or whatever code comes here
  24.     </xsl:for-each>
  25. </xsl:template>
  26.  
  27. </xsl:stylesheet>
I skipped the "root" div and the check for the <note> child, but it makes the divs as wanted.

regards

Am I a god now? *gg*
Oct 16 '08 #8
Dormilich
8,658 Expert Mod 8TB
Beautiful! Yes, you are a god. Honestly I don't know how some of you XSLT gurus got to where you are. It's a heck of a language to learn.
we got there by exercise. for me it was working on my website which uses an awful lot of xml (because I'm too lazy to write static html includes) and somehow the xml has to be displayed as html....

I don't find xsl complicated to learn since you have the standard loop and condition constucts like every other programming lanuage. for me the most difficult part (still) is getting the XPath expressions right (... I need to spend more time at my xsl article, *sigh* ...)

btw. your actual xml was much easier to use than your simplified sample

regards

and don't give up

your personal xsl deity
Oct 16 '08 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Jim Cobban | last post by:
I am using Xerces to read an XML file and load it into a DOM so I can update it and subsequently serialize the updated DOM. The problem I have is that as I traverse the DOM I would like to inform...
3
by: Plamen Valtchev | last post by:
This is my problem: From JavaScript I want to find the list of all defined/loaded JavaScript functions/objects/names within the current scope (html page in a browser). the page could contain...
1
by: alfred | last post by:
Hi my question is on traversing a tree with DOM. how would I be able to traverse 2 trees at the same time. I have 2 XML documents, with similar nodes. I would like to traverse 1 xml document,...
4
by: plmanikandan | last post by:
Hi, I am new to link list programming.I need to traverse from the end of link list.Is there any way to find the end of link list without traversing from start(i.e traversing from first to find the...
4
by: A_StClaire_ | last post by:
hi all, I'm trying to implement Huffman coding on letters of a string. I've written functions to define the initial leaf nodes (letters and their frequencies) and to sort them. I've also put...
4
by: Christian Rühl | last post by:
Good Day, folks! I'm having a problem traversing an XmlDocument tree in C#. I only want to access the InnerText of the leafs and the names of their ancestors and show them in a richTextBox. But...
3
joppe
by: joppe | last post by:
Hi! This is probably a stupid question, but I've searched and tried to find the answear for 4 hours now and im getting a little tired. Okay here it goes. I got a list containing a char *data...
30
by: asit | last post by:
We kno that data can be pushed onto the stack or popped 4m it. Can stack be traversed ??
1
by: somcool | last post by:
I am facing an error while traversing a query in MS Access Details - When I click a button, a form which has the query opens up. There are certain fields which are in the form of combo box in the...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.