473,513 Members | 2,307 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

xslt to HTML Transform question

I have an xml file similar to:
<menu>
<menuitem name="home" show="false"/>
<menuitem name="about" show="true"/>
<menuitem name="links" show="true"/>
<menuitem name="games" show="true"/>
<menuitem name="learn" show="true"/>
<menuitem name="order" show="true"/>
<menuitem name="contact" show="true"/>
<menuitem name="support" show="false"/>
<menuitem name="feedback" show="true"/>
....
</menu>

What I am trying to achieve is a table that takes every four menuitems
that are show="true" and put them in a table row and then put each
menuitem is a <td>..

Desired output:
<table>
<tr>
<td>about</td>
<td>links</td>
<td>games</td>
<td>learn</td>
</tr>
<tr>
<td>order</td>
<td>contact</td>
<td>feedback</td>
</tr>
</table>

I cannot figure out how to loop four and place them in a <trtag

What I have tried:
<xsl:template match="/">
<table>
<xsl:apply-templates select="menu"/>
</table>
</xsl:template>

<xsl:template match="menu">
<xsl:for-each select="menuitem[@show='true']">

<xsl:if test="position() mod 4 = 1">
<xsl:text >&lt;tr&gt;</xsl:text>
</xsl:if>

<td><xsl:value-of select="@name"/></td>

<xsl:if test="position() mod 4 = 0">
<xsl:text>&lt;tr&gt;</xsl:text>
</xsl:if>

</xsl:for-each>
</xsl:template>

There are a couple problems with this, 1. the position is still the
position of all menuitems true or false so I am not guaranteed 4 items
per row. 2. and most of all if actually right "<tr>" rather then
placing the <trtag in the html doc.

Any help would be great!

~Adam dR.

Nov 25 '06 #1
2 1682

Michael Kay's XSLT 2nd Edition has a decent explanation of
this class of problem, which can be found by looking in the index
for "tail recursion".
There are a couple problems with this, 1. the position is still the
position of all menuitems true or false
Couldn't quite grok that statement. Seems to me position()
would reflect the position of the nodelist formed by the
for-each select clause. xsltproc seemed to agree with my
assumption. Maybe I've missed something here.
per row. 2. and most of all if actually right "<tr>" rather then
placing the <trtag in the html doc.
That gets you to the nut: using recursion instead of iteration.
Here's one possible solution:

<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
version="1.0"
>
<xsl:output method="html" indent="yes"/>

<xsl:template name="EmitRows">
<xsl:param name="MenuItemList" />

<xsl:if test="count($MenuItemList) != 0">
<tr>
<xsl:for-each select="$MenuItemList[position() &lt; 5]">
<td><xsl:value-of select="@name" /></td>
</xsl:for-each>
</tr>
<xsl:call-template name="EmitRows">
<xsl:with-param name="MenuItemList"
select="$MenuItemList[position() &gt; 4]" />
</xsl:call-template>
</xsl:if>

</xsl:template>

<xsl:template match="/">
<table>
<xsl:apply-templates select="menu"/>
</table>
</xsl:template>

<xsl:template match="menu">
<xsl:call-template name="EmitRows">
<xsl:with-param name="MenuItemList"
select="./menuitem[@show='true']" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

xsltproc applies this XSLT file to your example XML data to produce:

<table>
<tr>
<td>about</td>
<td>links</td>
<td>games</td>
<td>learn</td>
</tr>
<tr>
<td>order</td>
<td>contact</td>
<td>feedback</td>
</tr>
</table>

Basic technique is to write a callable template that just returns
if the list is empty. If it's not empty, it does something useful with
one or more items at the front of the list, then passes all the other
items to itself recursively.

Hope this helps,
Ron Burk
www.xmlator.com

Nov 26 '06 #2
Michael Kay's XSLT 2nd Edition has a decent explanation of
this class of problem, which can be found by looking in the index
for "tail recursion".
Not all XSLT processors handle tail recursion gracefully. It is safer to use
another general method that just shortens dramatically the maximum size of
the call-stack needed -- DVC (Divide and Conquer). For example, to process
recursively a list of 1000000 (1M) items, the DVC method will use a stack
with maximum depth ~ 19 (log2(N) ).

One can read more about implementing DVC in XSLT here:

http://www.topxml.com/code/default.a...20020107050418
Or I'd recommend that one uses some of the most generic functions for
recursive processing, such as foldl(), implemented in the FXSL library. It
comes with most functions already implemented DVC, so one will not have to
do anything in addition but just use the functions.

Find more about FXSL here:

http://fxsl.sf.net (especially read the latest paper for the "Extreme
Markup Languages 2007" conference).
Cheers,
Dimitre Novatchev
<xm*****@gmail.comwrote in message
news:11**********************@l12g2000cwl.googlegr oups.com...
>
Michael Kay's XSLT 2nd Edition has a decent explanation of
this class of problem, which can be found by looking in the index
for "tail recursion".
>There are a couple problems with this, 1. the position is still the
position of all menuitems true or false

Couldn't quite grok that statement. Seems to me position()
would reflect the position of the nodelist formed by the
for-each select clause. xsltproc seemed to agree with my
assumption. Maybe I've missed something here.
>per row. 2. and most of all if actually right "<tr>" rather then
placing the <trtag in the html doc.

That gets you to the nut: using recursion instead of iteration.
Here's one possible solution:

<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
version="1.0"
>>
<xsl:output method="html" indent="yes"/>

<xsl:template name="EmitRows">
<xsl:param name="MenuItemList" />

<xsl:if test="count($MenuItemList) != 0">
<tr>
<xsl:for-each select="$MenuItemList[position() &lt; 5]">
<td><xsl:value-of select="@name" /></td>
</xsl:for-each>
</tr>
<xsl:call-template name="EmitRows">
<xsl:with-param name="MenuItemList"
select="$MenuItemList[position() &gt; 4]" />
</xsl:call-template>
</xsl:if>

</xsl:template>

<xsl:template match="/">
<table>
<xsl:apply-templates select="menu"/>
</table>
</xsl:template>

<xsl:template match="menu">
<xsl:call-template name="EmitRows">
<xsl:with-param name="MenuItemList"
select="./menuitem[@show='true']" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

xsltproc applies this XSLT file to your example XML data to produce:

<table>
<tr>
<td>about</td>
<td>links</td>
<td>games</td>
<td>learn</td>
</tr>
<tr>
<td>order</td>
<td>contact</td>
<td>feedback</td>
</tr>
</table>

Basic technique is to write a callable template that just returns
if the list is empty. If it's not empty, it does something useful with
one or more items at the front of the list, then passes all the other
items to itself recursively.

Hope this helps,
Ron Burk
www.xmlator.com

Nov 26 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
5556
by: Lisa | last post by:
I need to apply the HTML formatting tags and the French accented characters in a XML document. The XML is generated from a database that has HTML tags and French accented characters in the records....
1
363
by: Wil | last post by:
I'm very new to developing in .NET and even newer to XML. The past few days have been pretty frustrating for me because I'm trying to perform a transform on data in a dataset and it's not working....
5
4393
by: shauldar | last post by:
Is there a way (tool, hack...) to create an XSL:FO from an XSLT + XML files? My motivation is that we want to use a tool to design reports, and from that "design" generate both HTML (via XSLT)...
4
2143
by: Moogy | last post by:
I'm pulling my hair out here. First, I'm new to XML, so that doesn't help, but none of this makes any sense to me. All I'm trying to do is take a simple source XML file and translate it with an...
0
2337
by: Christopher M. Lauer | last post by:
I have done my best to answer this question but can not find the proper set of commands. I would like to transform an xml file (in code behind) and display its output in a specific html tag,...
5
1571
by: Patrick.O.Ige | last post by:
I have an xml and i'm trying to loop each node... When i do FOR EACH i seem not to get my desired result I want to loop through and get only the values that matches the question i specified with...
3
3071
by: Ian Roddis | last post by:
Hello, I want to embed SQL type queries within an XML data record. The XML looks something like this: <DISPLAYPAGE> <FIELD NAME="SERVER" TYPE="DROPDOWN"> <OPTION>1<OPTION> <OPTION>2<OPTION>...
3
1996
by: thomas.porschberg | last post by:
Hi, I want to read records from a database and export it in an arbitrary format. My idea was to feed a class with a String array fetched from the database and let this class fire SAX events as...
1
2711
by: Nick | last post by:
I am working on a website for a client and one of their requirements was to have a mailing list. I decided to XSLT to transform "templates" to HTML so that editing was very easy and less time...
12
11551
by: Chris | last post by:
Hi, Just wondering if anyone out there knows if it is possible to convert a CSV to xml using XSLT? I've seen a lot of examples of xml to CSV, but is it possible to go back the other way? I...
0
7265
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
7545
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...
1
7111
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...
0
7539
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
4751
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3240
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1605
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
807
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
461
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.