The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages - More
> XML Programming
|
Xsl to output a nested html list
Discuss Xsl to output a nested html list in the XML Programming forum on Dev Shed. Xsl to output a nested html list XML Programming forum discussing XML and related technologies, including XUL and XSL. XML is a self-describing file format, designed for maximum compatibility between applications.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

March 16th, 2011, 03:16 AM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
|
Xsl to output a nested html list
Hello,
I am having a basic problem which I just can’t seem to see the soultion to.
In short I am trying to output xml nodes into a nested html list.
The longer explanation:
Starting with this xml clip:
Code:
<Tasks>
<Task>
<ID>0</ID>
<Name>Wire frame markup</Name>
<OutlineLevel>1</OutlineLevel>
<Duration>PT2744H0M0S</Duration>
Under the <Tasks> node there are many <Task> nodes . Each <Task> has an own outline level. The node <OutlineLevel> has four possible values: one to four. I am trying to output the <Task> node as a nested HTML list with OutlineLevel determining the tasks placement in the list tree.
The xsl below produces a html page which looks right , but is semantic nonsense.
It outputs an unordered list for every single list item. This is obviously because the <ul> creation is done within the for-each loop.
Code:
<ul>
<xsl:for-each select="Project/Tasks/Task">
<xsl:choose>
<xsl:when test="OutlineLevel = 1">
<ul class="level1"><li>
<xsl:value-of select="Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after(Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{HyperlinkAddress}">
<xsl:value-of select="Hyperlink" />
</a>
</li></ul>
</xsl:when>
<xsl:when test="OutlineLevel = 2">
<ul class="level2"><li>
<xsl:value-of select="Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after(Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{HyperlinkAddress}">
<xsl:value-of select="Hyperlink" />
</a>
</li></ul>
</xsl:when>
<xsl:when test="OutlineLevel = 3">
<ul class="level3"><ul><li>
<xsl:value-of select="Name"/>,
( <b> <xsl:value-of select="(substring-before(substring-after(Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{HyperlinkAddress}">
<xsl:value-of select="Hyperlink" />
</a>
</li></ul></ul>
</xsl:when>
<xsl:when test="OutlineLevel = 0">
</xsl:when>
<xsl:otherwise>
<ul class="level4"><ul><ul><li>
<xsl:value-of select="Name"/>,
( <b> <xsl:value-of select="(substring-before(substring-after(Duration,'T'),'H') div 40)"/> weeks</b>),
<a href="{HyperlinkAddress}">
<xsl:value-of select="Hyperlink" />
</a>
</li></ul></ul></ul>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</ul>
I tried several things:
First, I thought the solution might be to simply move the <ul> declarations outside each <xsl:when test= > node. This didn’t work.
Code:
<ul class="level1">
<xsl:when test="OutlineLevel = 1">
<li>
<xsl:value-of select="Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after(Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{HyperlinkAddress}">
<xsl:value-of select="Hyperlink" />
</a>
</li>
</xsl:when>
</ul>
My next thought was that maybe this failed because it wasn’t recognized as valid xsl, so I tried wrap-ping the <ul> in a CDATA block hoping they would then be recognized as plain HTML and output as such. Also wrong
My final guess, and that is what they are at this point: guesses … my final guess was to try using xsl:text … again hoping a <ul> would be recognized and output as plain text/html. No such luck.
Code:
<xsl:text><ul class="level1"></xsl:text>
<xsl:when test="OutlineLevel = 1">
<li>
<xsl:value-of select="Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after(Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{HyperlinkAddress}">
<xsl:value-of select="Hyperlink" />
</a>
</li>
</xsl:when>
<xsl:text></ul></xsl:text>
So, it seems that there is no way to wrap <xsl:when test= > nodes in HTML elements.
Since I need to walk through each <Task> node and extract the relevant info, I see no alternative to using a for-each statement.
Can anyone give me a hint as to what I can try next?
|

March 16th, 2011, 05:58 AM
|
|
|
|
You like programming with a programming language that is not good in xsl
You have to think in templates
If the parser found a node must then describe how the template
the node replaced or re-created with html code
more information about xml-file
to handle the xml file
describe the output html
sorry for my bad english
__________________
Helmut Hagemann Germany
fallen to the bottom of the facts?
I reach my hand and we go together
wer lesen und google kann ist klar im Vorteil
who read and google is able is clear in the advantage
|

March 16th, 2011, 09:10 AM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
Hi,
thanks for the reply
Quote: | You have to think in templates |
I had, maybe wrongly, assumed that the <xsl:template> construct was just another way of doing the <xsl:for-each>
But, if I understand you correctly, you are saying <xsl:template> might work better in some situations: like here where I'm trying to output html in a very specific way.
|

March 25th, 2011, 02:44 AM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
Before I move on to trying another solution: can anyone confirm that there is no way to achieve my goal (original post above) with my current code or some variation thereof ?
Thanks and have a swell weekend 
|

March 28th, 2011, 05:51 AM
|
|
|
Please send me the original XML file
and the result of the html page that you want to have
It may also be other data
so you can then apply to your example
I do not understand what you're going to code in your example 
|

March 29th, 2011, 01:16 AM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
thank you :-)
Although I'm not sure how to send the files to you ... I tried "send a private message", but get an error message saying I don't have the rights to send private messages.
Is there another way I can get the files to you?
Quote: | Originally Posted by xml-profi Please send me the original XML file
and the result of the html page that you want to have
It may also be other data
so you can then apply to your example
I do not understand what you're going to code in your example  |
|

March 29th, 2011, 02:06 AM
|
|
|
|
use xml_user[@]web.de
|

March 29th, 2011, 02:40 AM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
|
just sent : thanks again for taking the time to look at this :-)
|

March 30th, 2011, 04:44 AM
|
|
|
Resolving a flat xml file
with the help of two template
the first template through all the task
since variable can be set only once the second template
find the new value
xml for testing
with the data from the email
xsl
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:variable name="project" select="Project"/>
<xsl:template match="/">
<html>
<head>
<title>Trial Management MS Project Overview</title>
<link rel="stylesheet" href="example.css" type="text/css" media="screen"/>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<meta http-equiv="Content-Language" content="en-us"/>
</head>
<body>
<h2>
<font face="tahoma" size="5">Steps for: <xsl:value-of select="Project/Subject"/></font>
</h2>Tasks: <br/>
<xsl:apply-templates select="Project"/>
</body>
</html>
</xsl:template>
<xsl:template match="Project">
<xsl:apply-templates select="Tasks"/>
</xsl:template>
<xsl:template match="Tasks">
<xsl:call-template name="levelsearch">
<xsl:with-param name="alltask" select="Task"/>
<xsl:with-param name="levelak" select="0"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="levelsearch">
<xsl:param name="alltask"/>
<xsl:param name="levelak"/>
<xsl:param name="ak" select="1"/>
<xsl:if test="count($alltask) > $ak">
<xsl:choose>
<xsl:when test="$levelak = 0">
<ul>
<xsl:attribute name="class">
<xsl:value-of select="concat('level',$levelak +1)"/>
</xsl:attribute>
<li>
<xsl:value-of select="$alltask[$ak +1]/Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after($alltask[$ak +1]/Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{$alltask[$ak +1]/HyperlinkAddress}">
<xsl:value-of select="$alltask[$ak +1]/Hyperlink"/>
</a>
</li>
<xsl:call-template name="levelsearch">
<xsl:with-param name="alltask" select="$alltask"/>
<xsl:with-param name="ak" select="$ak +1"/>
<xsl:with-param name="levelak" select="$alltask[$ak +1]/OutlineLevel"/>
</xsl:call-template>
</ul>
</xsl:when>
<xsl:when test="$levelak = $alltask[$ak+1]/OutlineLevel">
<li>
<xsl:value-of select="$alltask[$ak +1]/Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after($alltask[$ak +1]/Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{$alltask[$ak +1]/HyperlinkAddress}">
<xsl:value-of select="$alltask[$ak +1]/Hyperlink"/>
</a>
</li>
<xsl:call-template name="levelsearch">
<xsl:with-param name="alltask" select="$alltask"/>
<xsl:with-param name="ak" select="$ak+1"/>
<xsl:with-param name="levelak" select="$alltask[$ak +1]/OutlineLevel"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$levelak < $alltask[$ak +1]/OutlineLevel">
<ul>
<xsl:attribute name="class">
<xsl:value-of select="concat('level',$levelak +1)"/>
</xsl:attribute>
<li>
<xsl:value-of select="$alltask[$ak +1]/Name"/>,
( <b><xsl:value-of select="(substring-before(substring-after($alltask[$ak +1]/Duration,'T'),'H') div 40)"/> weeks</b> ),
<a href="{$alltask[$ak +1]/HyperlinkAddress}">
<xsl:value-of select="$alltask[$ak +1]/Hyperlink"/>
</a>
</li>
<xsl:call-template name="levelsearch">
<xsl:with-param name="alltask" select="$alltask"/>
<xsl:with-param name="ak" select="$ak+1"/>
<xsl:with-param name="levelak" select="$alltask[$ak +1]/OutlineLevel"/>
</xsl:call-template>
</ul>
<xsl:variable name="nextak">
<!-- define a variable with template -->
<xsl:call-template name="samelevel">
<xsl:with-param name="ak" select="$ak +1"/>
<xsl:with-param name="levelak" select="$levelak"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="levelsearch">
<xsl:with-param name="alltask" select="$alltask"/>
<xsl:with-param name="ak" select="$nextak"/>
<xsl:with-param name="levelak" select="$levelak"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="samelevel">
<!-- find the same level -->
<xsl:param name="ak"/>
<xsl:param name="levelak"/>
<xsl:choose>
<xsl:when test="$project/Tasks/Task[$ak]/OutlineLevel != $levelak">
<xsl:call-template name="samelevel">
<xsl:with-param name="ak" select="$ak +1"/>
<xsl:with-param name="levelak" select="$levelak"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ak -1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
result
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Trial Management MS Project Overview</title>
<link rel="stylesheet" href="example.css" type="text/css" media="screen">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Language" content="en-us">
</head>
<body>
<h2>
<font face="tahoma" size="5">Steps for: Planning and tracking </font>
</h2>Tasks:
<br>
<ul class="level1">
<li>INITIATION,
(
<b>38.4 weeks</b> ),
<a href="
http://www.cnn.com">initiation link</a>
</li>
<ul class="level2">
<li>FINAL DRAFT,
(
<b>0 weeks</b> ),
<a href=""></a>
</li>
<li>A plan,
(
<b>4.2 weeks</b> ),
<a href="
http://www.cnn.com">home home</a>
</li>
<ul class="level3">
<li>Create plan ,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare Risk Analysis plan,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare Communication plan,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare Training plan,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare other plan,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare Mitigation plan,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare Data ,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare Data Quality plan,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare lesson learned,
(
<b>4 weeks</b> ),
<a href=""></a>
</li>
</ul>
<li>
Information ,
(
<b>14 weeks</b> ),
<a href="
http://cnn.com">info link</a>
</li>
<ul class="level3">
<li>Identify members,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Plan preparation phase ,
(
<b>0.2 weeks</b> ),
<a href="
http://cnn.com">schedule</a>
</li>
<li>Request Invoice,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Appoint QC reviewer,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Writing,
(
<b>10.2 weeks</b> ),
<a href="
http://cnn.com">writing link</a>
</li>
<ul class="level4">
<li>Prepare first draft,
(
<b>4 weeks</b> ),
<a href="
http://cnn.com">where is this link</a>
</li>
<li>Index ,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Review ,
(
<b>1 weeks</b> ),
<a href=""></a>
</li>
<li>Update ,
(
<b>0.8 weeks</b> ),
<a href=""></a>
</li>
<li>Conduct review meeting,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Prepare second draft,
(
<b>1 weeks</b> ),
<a href=""></a>
</li>
<li>Review ,
(
<b>1 weeks</b> ),
<a href=""></a>
</li>
<li>Update ,
(
<b>1 weeks</b> ),
<a href=""></a>
</li>
<li>QC ,
(
<b>0.8 weeks</b> ),
<a href="
http://cnn.com">Link 1234</a>
</li>
<li>Requests,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
<li>Submit,
(
<b>0.2 weeks</b> ),
<a href="
http://cnn.com">home</a>
</li>
</ul>
<li>approval,
(
<b>2.8 weeks</b> ),
<a href="
http://cnn.com">dco 110021</a>
</li>
<ul class="level4">
<li>Review ,
(
<b>2 weeks</b> ),
<a href="
http://cnn.com">Link link</a>
</li>
<li>Answer comments,
(
<b>0.6 weeks</b> ),
<a href=""></a>
</li>
<li>How far is this ??,
(
<b>0.2 weeks</b> ),
<a href=""></a>
</li>
</ul>
</ul>
</ul>
</ul>
</body>
</html>
Last edited by xml-profi : March 30th, 2011 at 05:18 AM.
|

March 30th, 2011, 05:40 AM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
|
thanks so much for that well worked out reply :-))
Unfortunately, when i open the xml in a browser, it only shows the first bullet point: "Initiation" ... as if the iteration stopped there for some reason.
I'd like to attach a screenshot, but I can't seem to ...
sent to your email address instead.
thank again,
Tony
|

March 30th, 2011, 10:11 AM
|
|
|
|
I work with a stylus then it is done correctly
I try it with browser
xsl will stop
I know not why
I'm trying to figure out
|

March 30th, 2011, 10:40 AM
|
|
|
ther is by display in forum a problem with
< >
is not allow in xml
when see it in the xslt you must modify
Code:
<xsl:if test="count($alltask) > $ak">
or
<xsl:when test="$levelak < $alltask[$ak +1]/OutlineLevel">
< to <
> to >
Last edited by xml-profi : March 30th, 2011 at 10:53 AM.
|

March 30th, 2011, 01:45 PM
|
|
Registered User
|
|
Join Date: Mar 2011
Posts: 7
Time spent in forums: 2 h 59 m 47 sec
Reputation Power: 0
|
|
the updated files you sent worked: thanks again.
I look forward to examining your xsl and seeing how much I can learn.
Thanks again
Quote: | Originally Posted by xml-profi ther is by display in forum a problem with
< >
is not allow in xml
when see it in the xslt you must modify
Code:
<xsl:if test="count($alltask) > $ak">
or
<xsl:when test="$levelak < $alltask[$ak +1]/OutlineLevel">
< to <
> to >
|
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|