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 <tr> 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.