Subject: [xsl] document() as extension mechanism From: Joerg Pietschmann <joerg.pietschmann@xxxxxx> Date: Fri, 20 Jul 2001 17:46:46 +0200 |
Hello, i recently got some ideas for innovative uses of document() in conjunction with custom-written URIResolver's and XSL input sources. (Java only examples, sorry). Relevant questions are at the end of this post. 1. Read the current date/time. Refine the following hack to carefully designed and crafted code and insert it into your URIResolver's resolve method. if( href.startsWith("time:") ) { SAXSource source = new SAXSource(); source.setInputSource(new InputSource( new StringReader("<time>"+new Date().toString()+"</time>"))); return source; } Read the current date/time with <xsl:value-of select="document('time:foo')/time"/> The URL could be used to specify a locale, or a host to read from, or whatever you like (ideas welcome!). 2. Get a directory listing. You can read the listing into a string and feed it into the processor via a StringReader as in the example above, but it might be more interesting to demonstrate how to do this using a customized input source and XML reader. Drop this into your URIResolver: if( href.startsWith("filelist:") ) { return new SAXSource(new FileListXMLReader(), new FileListInputSource( new File(href.substring("filelist:".length())))); } You'll need an apropriate InputSource (terseness favoured over robustness): import java.io.*; import java.util.*; import org.xml.sax.*; public class FileListInputSource extends InputSource { private File dir; public FileListInputSource(File d) { dir=d; } public String[] list() { return dir.list(); } } The Reader class is somewhat more elaborated. Getting strings through the SAX API sucks mightily (is there a better way than shown below?). The only really interesting routine is parse(InputSource) buried somewhere in the middle of the following code: import java.io.*; import java.util.*; import org.xml.sax.*; public class FileListXMLReader implements XMLReader { private int len=128; private char buf[]=new char[len]; private synchronized void writeContent (ContentHandler contentHandler,String s) throws SAXException { if( s.length()>len ) { do {len=2*len;} while( s.length()>len ); buf=new char[len]; } s.getChars(0,s.length(),buf,0); contentHandler.characters(buf,0,s.length()); } // XML Reader private ContentHandler contentHandler; private DTDHandler dtdHandler; private EntityResolver entityResolver; private ErrorHandler errorHandler; public ContentHandler getContentHandler() { return contentHandler; } public DTDHandler getDTDHandler() { return dtdHandler; } public EntityResolver getEntityResolver() { return entityResolver; } public ErrorHandler getErrorHandler() { return errorHandler; } public boolean getFeature(java.lang.String name) throws SAXNotRecognizedException, SAXNotSupportedException { if( name.equals("http://xml.org/sax/features/namespaces") || name.equals("http://xml.org/sax/features/namespace-prefixes") ) { return true; } else { throw new SAXNotRecognizedException("not implemented: "+name); } } public java.lang.Object getProperty(java.lang.String name) throws SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotRecognizedException("not implemented: "+name); } public void parse(InputSource input) throws java.io.IOException, SAXException { if( contentHandler==null ) { throw new SAXException("No content handler"); } try { FileListInputSource source=(FileListInputSource)input; Attributes attrs=new org.xml.sax.helpers.AttributesImpl(); contentHandler.startDocument(); contentHandler.startElement("","files","files",attrs); String list[]=source.list(); if( list!=null ) { for( int i=0;i<list.length;i++ ) { contentHandler.startElement("","file","file",attrs); writeContent(contentHandler,list[i]); contentHandler.endElement("","file","file"); } } contentHandler.endElement("","files","files"); contentHandler.endDocument(); } catch( ClassCastException e ) { throw new SAXException("Need filelist input source"); } } public void parse(java.lang.String systemId) throws java.io.IOException, SAXException { // leave this to your imagination, should use new File(systemId).list() return; } public void setContentHandler(ContentHandler handler) { contentHandler=handler; } public void setDTDHandler(DTDHandler handler) { dtdHandler=handler; } public void setEntityResolver(EntityResolver resolver) { entityResolver=resolver; } public void setErrorHandler(ErrorHandler handler) { errorHandler=handler; } public void setFeature(java.lang.String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { if( name.equals("http://xml.org/sax/features/namespaces") || name.equals("http://xml.org/sax/features/namespace-prefixes") ) { } else { throw new SAXNotRecognizedException("not implemented: "+name); } } public void setProperty(java.lang.String name, java.lang.Object value) throws SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotRecognizedException("not implemented"); } } The following snippet will insert a listing of the current directory of the process into an html-page: <xsl:for-each select="document('filelist:.')/files/*"> <p><xsl:value-of select="."/></p> </xsl:for-each> You can easily extend the XMLReader to provide file lengths, modification dates, diverse attributes and whatnot to the XSL processor (use listFiles() instead of list()). If you use TrAX/JAXP you can also use the FileListXMLReader for as your main document input source (yes, this can be useful too: directory listing pages, styled as you like...). 3. Another idea: read parameters of a servlet with document('parameters:'). Unfortunately, the code ist too long to be quoted here :-) Saxon allows to specify the URI resolver on the command line, therefore you don't need to deal with the source of of the processor just for experimenting. java -classpath ".;saxon.jar" com.icl.saxon.StyleSheet \ -r MyURIResolver foo.xml foo.xsl If you use TrAX/JAXP, invoke setURIResolver on your transformer. Questions: 1. I think this should provide a rather portable way to allow access to various system ressources at lease for Java-based processors. What's your opinion? 2. Other ideas? 3. Anybody out there wanting to host a repository for resolvers/sources? :-) 4. Could this be of interest to the standards people? Regards J.Pietschmann -- XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] getting XSL to ignore a l, Hewko, Doug | Thread | RE: [xsl] document() as extension m, Michael Kay |
RE: [xsl] Apologies and 2 questions, Nathan Shaw | Date | Re: [xsl] Creating a tree variable , Wendell Piez |
Month |