It is certainly possible to apply a similar scheme to attributes in the XML document, you just need to make sure you generate the XPath correctly.
Here is an adapted sample that makes use of the following XML:
Code:
<Detail>
<UpdateData ID="887618" GUID="6fa81a06-fe17-4941-bb3c-de597afd29d0" BulletinID="" KBID="887618" Type="2" IsAuthorized="false" IsInstalled="true" Severity="0" RestartRequired="false">
<Title>Office 2003 Service Pack 2 for Proofing Tools</Title></UpdateData>
<UpdateData ID="2" GUID="6fa81a06-fe17-4941-bb3c-de597afd29de" BulletinID="1" KBID="887618" Type="2" IsAuthorized="true" IsInstalled="false" Severity="0" RestartRequired="false">
<Title>whatever</Title></UpdateData>
</Detail>
Then here is an XSLT 1.0 stylesheet that transforms the XML into a HTML table where some attributes are transformed into HTML checkbox controls, some attributes and child elements into HTML text controls, and some attributes simply into readonly table cells. I have improved the XPath generation from the last sample so that it should work more generically, at least as long as namespaces do not come into play:
Code:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Detail">
<table border="1">
<thead>
<tr>
<xsl:apply-templates select="UpdateData[1]/@* | UpdateData[1]/*" mode="th"/>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="UpdateData"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="UpdateData/@* | UpdateData/*" mode="th">
<th>
<xsl:value-of select="name()"/>
</th>
</xsl:template>
<xsl:template match="UpdateData">
<tr>
<xsl:apply-templates select="@* | *"/>
</tr>
</xsl:template>
<!-- transform child element or attribute into checkbox -->
<xsl:template match="UpdateData/@IsAuthorized | UpdateData/@IsInstalled">
<xsl:variable name="xpath">
<xsl:apply-templates select="." mode="xpath"/>
</xsl:variable>
<td>
<input type="checkbox"
name="{$xpath}"
value="{.}"
onclick="updateCheckbox(this);">
<xsl:if test=". = 'true'">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
</input>
</td>
</xsl:template>
<!-- transform child element or attribute into readonly table cell -->
<xsl:template match="UpdateData/@ID | UpdateData/@GUID | UpdateData/@BulletinID | UpdateData/@KBID | UpdateData/@RestartRequired">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
<!-- transform child element or attribute into input type="text" -->
<xsl:template match="UpdateData/Title | UpdateData/@Type | UpdateData/@Severity">
<xsl:variable name="xpath">
<xsl:apply-templates select="." mode="xpath"/>
</xsl:variable>
<td>
<input type="text"
name="{$xpath}"
value="{.}"
onchange="updateText(this);"/>
</td>
</xsl:template>
<xsl:template match="*" mode="xpath">
<xsl:for-each select="ancestor::*">
<xsl:value-of select="concat('/', name(), '[')"/>
<xsl:number/>
<xsl:text>]</xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match="@*" mode="xpath">
<xsl:for-each select="ancestor::*">
<xsl:value-of select="concat('/', name(), '[')"/>
<xsl:number/>
<xsl:text>]</xsl:text>
</xsl:for-each>
<xsl:value-of select="concat('/@', name())"/>
</xsl:template>
</xsl:stylesheet>
Here is the sample HTA code, now having two functions, one for updating boolean values from a checkbox control, one for updating text elements or attributes from a text control:
Code:
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HTA test</title>
<script type="text/javascript">
var xmlUrl = 'test2009051201.xml';
var xslUrl = 'test2009051201Xsl.xml';
var outputUrl = 'test2009051201Output.xml';
</script>
<script type="text/javascript">
var msxmlVersion = '3.0';
var doc, sheet;
function updateCheckbox(cb)
{
doc.selectSingleNode(cb.name).text = cb.checked ? 'true' : 'false';
}
function updateText(input)
{
doc.selectSingleNode(input.name).text = input.value;
}
function load()
{
doc = new ActiveXObject('Msxml2.DOMDocument.' + msxmlVersion);
doc.async = false;
doc.load(xmlUrl);
doc.setProperty('SelectionLanguage', 'XPath');
sheet = new ActiveXObject('Msxml2.DOMDocument.' + msxmlVersion);
sheet.async = false;
sheet.load(xslUrl);
document.getElementById('ph1').innerHTML = doc.transformNode(sheet);
}
window.onload = load;
</script>
</head>
<body>
<h1>Example</h1>
<div id="ph1"></div>
<div>
<input type="button" value="save" onclick="doc.save(outputUrl);">
</div>
</body>
</html>