Abstract

  • Data is sent to browser as either XML embedded within HTML, or XML over AJAX request.
  • Javascript runs XSL rules on the XML to transform it into HTML.
  • Newly generated HTML is inserted into DOM.
  • This allows sorting, paging, etc.

Tools

  • xstream to do java object -> XML conversion
  • sarissa to do XML transform in the browser; uses the browser’s own XSTL engine; currently works well in at least IE and Firefox
  • (optional) ajaxslt is an alternative that does the transform using pure javascript, useful if wide cross-browser compatibility is important (but, has heavy performance cost — good for only small datasets)

Technique

#1 Convert object to XML, insert into HTML

The java code:

XStream xstream = new XStream();
// optional, use short names instead of full class
// names in generated xml
xstream.alias("lot", LotSearchResult.class);
xstream.alias("saleList", SaleList.class);
xml = xstream.toXML(saleList);

The jsp code:

<textarea id="hiddenXML" style="display:none">
  ${xml}
</textarea>

The generated XML looks like this, in this example:

<saleList>
  <otherAttribute>50</otherAttribute>
  <searchResults>
    <lot>
      <lotId>3803086</lotId>
      <!-- and so forth -->
    </lot>
  </searchResults>
</saleList>

It’s embedded within the text area so that the browser doesn’t attempt to parse it. Note that you could just as well obtain the XML over an AJAX call, but for prototyping purposes I embedded it in text areas.

#2 Embed the XSL inside the HTML

<textarea id="hiddenXSL_1" style="display:none">
  <xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:template match="lot">
	<tr>
	  <td><xsl:value-of select="lotId"/></td>
          <!-- and so on -->
	</tr>
     </xsl:template>

     <xsl:template match="/">
	<table width="980" cellpadding="2" border="1" bordercolor="#eeeeee" align="center"
	  cellspacing="0">
        <tr>
	  <td class="searchltsmc">
               <span class="fakelink" onclick="writeTable('lotId')">
                  Lot   #
               </span>
          </td>
          <!-- and so on -->
        </tr>
	<xsl:apply-templates select="saleList/searchResults/lot">
	  @sort@
	</xsl:apply-templates>
      </table>
    </xsl:template>
  </xsl:stylesheet>
</textarea>

#3 Use the Sarissa javascript library to transform

function writeTable(sort)
{
	var processor = new XSLTProcessor();
	var xsl = document.getElementById("hiddenXSL_1").value;
	xsl = xsl.replace(/@sort@/,
               "<xsl:sort select='" + sort +
               "' order='descending'/>");
	var xml = document.getElementById("hiddenXML").value;
	var xslDoc = (new DOMParser())
                          .parseFromString(xsl, "application/xml");
	var xmlDoc = (new DOMParser())
                          .parseFromString(xml, "application/xml");
	processor.importStylesheet(xslDoc);
	var newDoc = processor.transformToDocument(xmlDoc);
	var ser = new XMLSerializer();
	document.getElementById("datatable").innerHTML =
              ser.serializeToString(newDoc);
}

#3b Google javascript alternative

function writeTableGoogle(sort)
{
	// XXX do the @sort@ replacement as above
	var xml = xmlParse(
                     document.getElementById("hiddenXML").value);
	var xsl = xmlParse(
                     document.getElementById("hiddenXSL_1").value);
	var html = xsltProcess(xml, xsl);
	document.getElementById("datatable").innerHTML = html;
}


Related Leave a Comment