Dynamic Documents / Creating a node-set in Java

Subject: Dynamic Documents / Creating a node-set in Java
From: "Clark C. Evans" <clark.evans@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 5 Oct 1999 02:41:51 -0400 (EDT)
James,

For several reasons, I'm trying to return a node-set
to XSL stylesheet from Java.  My next step (after this one)
is to enable SQL queries to bring back "dynamic" documents
using a JDBC connection.  Anyway, to get the ball rolling,
I've tried to build a HashtableAdapter; one that is
for-each friendly.  I'm half way there, but I can't
figure out how to generate a good NameTable.  Currently,
a list of nodes returns, but none of the axis seem
to be enabled (for children and attributes).

Could you look at it and give me a few pointers?

Thanks Tons!

Clark

......................................


package com.clarkevans.xtk;

import java.io.*;
import java.util.Hashtable;
import java.util.Enumeration;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import com.jclark.xsl.om.*;
import com.jclark.xsl.sax.*;


public class HashtableAdapter {
  
  private static Hashtable table_of_tables = new Hashtable();
  private static Exception     last_error      = null;

  private static Hashtable getTable( String name )
  {
    Hashtable ret = (Hashtable) table_of_tables.get(name);
    if( null == ret )
    {
	ret = new Hashtable();
        table_of_tables.put(name,ret);
    }
    return ret;
  }

  public static void put( String table, String key, String value )
  {
     getTable(table).put(key,value);        
  }
  public static String remove( String table, String key)
  {
    return (String) getTable(table).remove(key);
  }
  public static String get( String table, String key )
  {
    return (String) getTable(table).get(key);
  }
  public static int size(String table)
  {
    return getTable(table).size();
  }
  public static String toString(String table)
  {
    String     list = new String();
    Hashtable   tab = getTable(table);
    for (Enumeration e = tab.keys() ; e.hasMoreElements() ;) {
       String key   = (String) e.nextElement(); 
       String value = (String) tab.get(key);
       list += wrap("entry",wrap("key",key)+wrap("value",value));
    }
    return wrap("table",list);
  }
  public static String wrap(String element, String content)
  {
    return "<" + element + ">"  + content + "</" + element + ">";
  }
  public static NodeIterator toNodeList(String table)
  {
    try
    {
      XMLProcessorImpl proc = new XMLProcessorImpl(
                              new HashtableParser(
                                getTable(table)));
      Node root = proc.load( new InputSource(),
                           0, new LoadContextImpl(),
                              new NameTableImpl() );
      return root.getChildren();
    }
    catch (Exception e)
    {
      last_error = e;
      return null;
    }
  }

  public static String getLastError()
  {
    if(null != last_error) {
      StringWriter w = new StringWriter();
      last_error.printStackTrace(new PrintWriter(w));
      last_error = null;
      return w.toString();
    }
    return "";
  }   

  private static class LoadContextImpl implements LoadContext 
  {
      public boolean getStripSource(Name elementTypeName) { return false;
}
      public boolean getIncludeComments() { return true; }
      public boolean getIncludeProcessingInstructions() { return true; }
  }

  private static class HashtableParser implements Parser
  {
    Hashtable       table;
    DocumentHandler handler;
    public void setLocale (java.util.Locale locale) throws SAXException {}
    public void setEntityResolver (EntityResolver resolver) {}
    public void setDTDHandler (DTDHandler handler) {}
    public void setErrorHandler (ErrorHandler handler) {}
    public void setDocumentHandler (DocumentHandler handler) { 
      this.handler = handler; 
    }
    public void parse (InputSource source) throws SAXException {
      parse(); 
    }
    public void parse (String systemId) throws SAXException {
      parse();
    }
    HashtableParser(Hashtable table)
    {
      this.table = table;
    }
    private void parse()
    {
      try
      {
        handler.startDocument();
        for (Enumeration e = table.keys() ; e.hasMoreElements() ;) {
          AttributeListImpl al  = new AttributeListImpl();
          String key   = (String) e.nextElement();
          String value = (String) table.get(key);
          al.addAttribute("key","CDATA",key);
          al.addAttribute("value","CDATA", value);
          handler.startElement("entry",al);
          handler.startElement("key", new AttributeListImpl() );
          handler.characters( key.toCharArray(),0,key.length());
          handler.endElement("key");
          handler.startElement("value", new AttributeListImpl());
          handler.characters( value.toCharArray(), 0, value.length());
          handler.endElement("value");
          handler.endElement("entry");
        }
        handler.endDocument();
      }
      catch( Exception e )
      {
        table.put("exception",e.toString());
      }
    }
  }
}



/******** Here is a test stylesheet **************************
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/XSL/Transform/1.0";
  xmlns="http://www.w3.org/TR/REC-html40";

xmlns:ht="http://www.jclark.com/xt/java/com.clarkevans.xtk.HashtableAdapter";
  result-ns="">
     
<xsl:template match="/">
   <html>
   <xsl:value-of select="ht:put('table','a','1')" />
   <xsl:value-of select="ht:put('table','b','2')" />

   <xsl:for-each select="ht:to-node-list('table')" >
     <xsl:if test="position()=1" > { </xsl:if>
     Content: <xsl:value-of select="."   />
     Name: <xsl:value-of select="name()" />
     Text: <xsl:value-of select="text()" />
     KeyA: <xsl:value-of select="attribute::key" />
     ValA: <xsl:value-of select="attribute::value" />
     KeyC: <xsl:value-of select="child::key" />
     ValC: <xsl:value-of select="child::value" />
     <xsl:if test="position()=last()" >}</xsl:if>           
   </xsl:for-each>
   <xsl:value-of select="ht:to-string('table')" />
   <xsl:value-of select="ht:get-last-error()" />
  </html>
</xsl:template>

</xsl:stylesheet>
************************************************************/

/****** Here is the current output ************************** 

   { Content: b2 Name: entry Text: KeyA: ValA: KeyC: ValC: 
     Content: a2 Name: entry Text: KeyA: ValA: KeyC: ValC:
   }<table><entry><key>b</key><value>2</value></entry><entry><key>a</key>
   <value>1</value></entry></table>

************************************************************/

/****** Here is the expected output ************************** 

   { Content: b2 Name: entry Text: b2  KeyA: b ValA: 2 KeyC: b ValC: 2 
     Content: a1 Name: entry Text: a1  KeyA: a ValA: 1 KeyC: a ValC: 1
   }<table><entry><key>b</key><value>2</value></entry><entry><key>a</key>
   <value>1</value></entry></table>

************************************************************/






 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread