By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,706 Members | 1,105 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,706 IT Pros & Developers. It's quick & easy.

Tables with show/hide from XML using XSLT

P: n/a
I have been desperately looking for a treeview-type solution for my
problem
for the past three weeks and have been greatly unsuccessful. I am
totally
new to the world of XSLT and I *don't know* JavaScript. Still, I have
managed to get something together, which I am putting across here. Any
help (even pointing me to the place to look) is welcome.

The problem I have is as follows:

I have the following XML -

<?xml version=3D" 1.0" encoding=3D"UTF-8"?>
<Root>
<Table1>
<fld1>0</fld1>
<disc1>
<dfld1>7</dfld1>
<loop3>
<lfld2>170</lfld2>

<loop4><lfld3>45</lfld3></loop4>
</loop3>
<fld3>37</fld3>
</disc1>

<loop1><lfld1>1030</lfld1><lfld1>4574</lfld1><lfld1>1341</lfld1></loop1>
<loop1><lfld1>1031</lfld1>
<loop2>
<disc1><dfld1>7</dfld1>
<loop3><lfld2>170</lfld2>

<loop4><lfld3>40</lfld3></loop4>
</loop3>
<loop3><lfld2>170</lfld2>

<loop4><lfld3>40</lfld3></loop4>
</loop3>
<fld3>1025</fld3>
</disc1>
<disc2><dfld1>7</dfld1>
<loop3><lfld2>170</lfld2>

<loop4><lfld3>40</lfld3></loop4>
</loop3>
<loop3><lfld2>170</lfld2>

<loop4><lfld3>40</lfld3></loop4>

<loop4><lfld3>50</lfld3></loop4>

<loop4><lfld3>60</lfld3></loop4>
</loop3>
<fld3>1025</fld3>
</disc2>
</loop2>
<fld10>1024</fld10>
</loop1>
</Table1>
</Root>

and I require an XSLT to produce an HTML which would do the following:
(I will put in (-) symbols where I want it to expand and collapse. And
yes,
you are right that I want it to collapse to a single row when
collapsed.
(-) Root
(-)table1
fld1 0
(-)disc1 dfld1 0
(-)loop1
ldfld1 10
dfld2 3005
(-)loop1
ldfld1 238
(-) loop2
ldfld2 3847
ldfld2 472
and so on...

when in collapsed state the above should look like
first look : (+) Root

second look : (-) Root
(+) table1
(+) table2
(+) table3

next look: (-) Root
(-) table1
fld1 0
(+) disc1
fld2 34765
(+) table2
(+) table3

and so on...

The XSLT I have put together as of now is:

<?xml version=3D"1.0"?>
<xsl:stylesheet xmlns:xsl=3D" http://www.w3.org/1999/XSL/Transform"
version=
=3D"
1.0">
<xsl:template match=3D"/Root">
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html;
charset=3DUTF-8">
<script language=3D"JavaScript" src=3D"CollapsibleRows.js"> </script>
<style type=3D"text/css">
//
body {
font-family:arial, sans-serif;
font-size:76%;
}
/**/
</style>
</meta>
<title>Converting XML to Table</title>
</head>
<body>
<table class=3D"collapsible" border=3D"1" cellpadding=3D"0"
cellspacing=
=3D"0"
width=3D"500">
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match=3D"table">
<td width=3D"500">
<xsl:value-of select=3D"@name"/>
</td>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match=3D"tag">
<td>
<xsl:value-of select=3D"@field"/>
<br/>
<xsl:value-of select=3D"@value"/>
</td>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match=3D"disc">
<tr>
<td>
<table class=3D"collapsible" border=3D"1" width=3D"100%"
cellpadding=3D"=
0"
cellspacing=3D"0">
<td>
<xsl:value-of select=3D"@name"/>
</td>
<xsl:apply-templates/>
</table>
</td>
</tr>
</xsl:template>
<xsl:template match=3D"Loop">
<tr>
<td>
<table class=3D"collapsible" border=3D"1" width=3D"100%"
cellpadding=3D"=
0"
cellspacing=3D"0">
<td>
<xsl:value-of select=3D"@name"/>
</td>
<xsl:apply-templates/>
</table>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>

and the Javascript I am using is:
var W3CDOM =3D (document.createElement &&
document.getElementsByTagName);

addEvent(window, 'load', initCollapsingRows);

// This is the path to the images relative to the HTML file
// Ex. If your HTML file is at /files/Index.html
// and your JavaScript and images are in /files/collapsible/
// then the path here would be "collapsible/"
var pathToImages =3D "";

function addEvent(obj, eventType,fn, useCapture)
{
if (obj.addEventListener) {
obj.addEventListener(eventType, fn, useCapture);
return true;
} else {
if (obj.attachEvent ) {
var r =3D obj.attachEvent ("on"+eventType, fn);
return r;
}
}
}

// this function is needed to work around
// a bug in IE related to element attributes
function hasClass(obj) {
var result =3D false;
if (obj.getAttributeNode("class") !=3D null) {
result =3D obj.getAttributeNode("class").value;
}
return result;
}

function toggleVisibility() {

var theImage =3D this;
var theRowName =3D this.id.replace('_image', '_comment');
var theRow =3D document.getElementById(theRowName);

if (theRow.style.display=3D=3D"none") {
theRow.style.display =3D "";
theImage.src =3D pathToImages + "Collapse.gif";
} else {
theRow.style.display =3D "none";
theImage.src =3D pathToImages + " Expand.gif ";
}
}

function insertExtraCells(theTable) {

// get reference to all of the tbody's, thead's, and tfoot's
var tbodies =3D theTable.getElementsByTagName('tbody');
var theads =3D theTable.getElementsByTagName('thead');
var tfoots =3D theTable.getElementsByTagName ('tfoot');

insertInto(theads, 'th');
insertInto(tbodies, 'td');
insertInto(tfoots, 'td');

}

function insertInto(parentCollections, typeOfCell) {
// loop through all of the parent collections passed in
for (var m =3D 0; m < parentCollections.length; m++) {

// get all of the rows for each collection
var trs =3D parentCollections[m].getElementsByTagName('tr');

// loop through each of the rows
for (i=3D0;i<trs.length;i++) {
// create a new cell
var theNewCell =3D document.createElement(typeOfCell);

// insert the new cell before the first child
var cells =3D trs[i].getElementsByTagName(typeOfCell);
trs[i].insertBefore(theNewCell, cells[0]);
}
}
}

function initCollapsingRows()
{
if (!W3CDOM) return;

// the flag we'll use to keep track of
// whether the current row is odd or even
var even =3D true;

// get a list of all the tables
var tables =3D document.getElementsByTagName('table');

// if there aren't any tables exit
if (tables.length=3D=3D0) { return; }

// and iterate through them...
for (var k =3D 0; k < tables.length; k++) {

// if the table has a class
if (hasClass(tables[k])) {

// if that class is "collapsible"
if
(tables[k].getAttributeNode('class').value.indexOf('collapsi ble')!=3D-1)
{

// since we are adding a graphic for expanding and
collapsing
// the rows in the first column of the table, we need to
ad=
d

// an extra column everywhere
insertExtraCells(tables[k]);

var tbodies =3D tables[k].getElementsByTagName('tbody');
// iterate through the bodies...
for (var h =3D 0; h < tbodies.length; h++) {

// find all the &lt;tr&gt; elements...
var trs =3D tbodies[h].getElementsByTagName('tr');

// ... and iterate through them
for (var i =3D 0; i < trs.length; i++) {

if (i%2=3D=3D0) {
// Get a reference to the TD's
var td =3D
trs[i].getElementsByTagName('td')[0]=
;

// Assign a related unique ID to the next
row
where the comment is
// This is the row that will be expanded and

collapsed
var theRowName =3D "row_" + i + "_comment";
trs[i+1].id =3D theRowName;
trs[i+1].style.display =3D "none";

// Create the new image object
var theNewImage =3D
document.createElement('img=
');

var theNewImageName =3D "row_" + i +
"_image";
theNewImage.id =3D theNewImageName;
theNewImage.src =3D pathToImages + "
Expand.gif=
";
theNewImage.width =3D 13;
theNewImage.height =3D 13;
theNewImage.style.margin =3D "5px";
theNewImage.style.cursor =3D "pointer";

// Add "onclick" event to the image that
expand=
s
and collapses the next row
theNewImage.onclick =3D toggleVisibility;

// Insert an image into the document tree
insid=
e
the first TD
td.appendChild(theNewImage);
td.style.width=3D"1%"

// Skip the collapsbile row
i++;
}
}
}
}
}
// Reset "even" for the next table
even =3D true;
} // End for loop
}

Could you let me know if it is doable (at least if I change the XML
format
to an attribute level one like - <tag f="fieldname" v="value"/>). I am
really desperate for an answer and have searched the net innumerable
times and written to almost all the mailing lists without any success.

Thanks a lot for taking time out for this.

Apr 21 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Scamjunk wrote:
I have been desperately looking for a treeview-type solution for my
problem
for the past three weeks and have been greatly unsuccessful. I am
totally
new to the world of XSLT and I *don't know* JavaScript. Still, I have
managed to get something together, which I am putting across here. Any
help (even pointing me to the place to look) is welcome.

The problem I have is as follows:

[details snipped]


Are you sure that your XML is valid? Your first line looks odd to me,
you don't have a doctype declaration, there's no namespace declaration,
and two of your elements have names that aren't all in lowercase.

I have no idea if the above is relevant to your problem, since I don't
know anything about using XML!

Anyway, I don't know that this ng is truly appropriate for your
problem. What about the following, which seems like a good bet for
getting useful advice on XSLTs:
comp.text.xml
--
AGw.

Apr 21 '06 #2

P: n/a
I don't know where the '3D's came in from. Maybe some problem with the
display part of google groups. I sure didn't put them in. The point is
that I generate my XMLs through DOM and hence, I didn't feel the
necessity to put in namespaces. and then want to display them in the
format specified using XSLT. I have come to understand that it is
doable. It is just that I don't know javascript to do it. Can anybody
at least point me to the right place to look for a solution ?

Scam.

Apr 24 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.