You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mo...@apache.org on 2001/05/22 19:28:13 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/runtime Hashtable.java AbstractTranslet.java AttributeList.java BasisLibrary.java DefaultRun.java DefaultSAXOutputHandler.java TextOutput.java

morten      01/05/22 10:28:10

  Modified:    java/src/org/apache/xalan/xsltc/compiler Whitespace.java
               java/src/org/apache/xalan/xsltc/dom DOMImpl.java
                        DTDMonitor.java KeyIndex.java MultiDOM.java
               java/src/org/apache/xalan/xsltc/runtime
                        AbstractTranslet.java AttributeList.java
                        BasisLibrary.java DefaultRun.java
                        DefaultSAXOutputHandler.java TextOutput.java
  Added:       java/src/org/apache/xalan/xsltc/runtime Hashtable.java
  Log:
  Major performance improvement. I removed all references to
  java.util.Hashtable in the XSLTC runtime directory. I added my own
  implementation of Hashtable (based on the Java1.1 implementation, but
  without any synchronized methods and with some performance improvements).
  Some minor changes in the internal DOM - also for better performance.
  A small change in the DOMImpl.getNamespaceName() method to prevent null-
  pointer exceptions in some rare cases where the xsl:strip/preserve-space
  elements were used.
  Eliminated one String instantiation on the TextOutput class.
  
  Revision  Changes    Path
  1.3       +1 -2      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Whitespace.java
  
  Index: Whitespace.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Whitespace.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Whitespace.java	2001/05/02 10:25:17	1.2
  +++ Whitespace.java	2001/05/22 17:26:15	1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Whitespace.java,v 1.2 2001/05/02 10:25:17 morten Exp $
  + * @(#)$Id: Whitespace.java,v 1.3 2001/05/22 17:26:15 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -408,7 +408,6 @@
   						      "(I)Ljava/lang/String;");
   
   	    final int strcmp = cpg.addMethodref("java/lang/String",
  -						//"compareToIgnoreCase",
   						"compareTo",
   						"(Ljava/lang/String;)I");
   
  
  
  
  1.8       +44 -27    xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java
  
  Index: DOMImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- DOMImpl.java	2001/05/21 15:13:00	1.7
  +++ DOMImpl.java	2001/05/22 17:26:31	1.8
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DOMImpl.java,v 1.7 2001/05/21 15:13:00 morten Exp $
  + * @(#)$Id: DOMImpl.java,v 1.8 2001/05/22 17:26:31 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -73,7 +73,6 @@
   import java.io.ObjectInput;
   import java.io.ObjectOutput;
   import java.io.IOException;
  -import java.util.Hashtable;
   import java.util.Dictionary;
   import java.util.Enumeration;
   import java.util.Stack;
  @@ -89,6 +88,7 @@
   import org.apache.xalan.xsltc.util.IntegerArray;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   import org.apache.xalan.xsltc.runtime.SAXAdapter;
  +import org.apache.xalan.xsltc.runtime.Hashtable;
   
   public final class DOMImpl implements DOM, Externalizable {
   
  @@ -1709,17 +1709,18 @@
        * Get mapping from DOM element/attribute types to external types
        */
       public short[] getMapping(String[] names) {
  +	int i;
   	final int namesLength = names.length;
   	final int mappingLength = _namesArray.length + NTYPES;
   	final short[] result = new short[mappingLength];
   
   	// primitive types map to themselves
  -	for (int i = 0; i < NTYPES; i++)
  +	for (i = 0; i < NTYPES; i++)
   	    result[i] = (short)i;
   
   	// extended types initialized to "beyond caller's types"
   	// unknown element or Attr
  -	for (int i = NTYPES; i < mappingLength; i++) {
  +	for (i = NTYPES; i < mappingLength; i++) {
   	    final String name = _namesArray[i - NTYPES];
   	    final int atPos = name.lastIndexOf(':')+1;
   	    result[i] = (short)(name.charAt(atPos) == '@'
  @@ -1727,7 +1728,7 @@
   	}
   
   	// actual mapping of caller requested names
  -	for (int i = 0; i < namesLength; i++) {
  +	for (i = 0; i < namesLength; i++) {
   	    result[getGeneralizedType(names[i])] = (short)(i + NTYPES);
   	}
                
  @@ -1739,13 +1740,14 @@
        * Get mapping from external element/attribute types to DOM types
        */
       public short[] getReverseMapping(String[] names) {
  +	int i;
   	final short[] result = new short[names.length + NTYPES];
   	// primitive types map to themselves
  -	for (int i = 0; i < NTYPES; i++) {
  +	for (i = 0; i < NTYPES; i++) {
   	    result[i] = (short)i;
   	}
   	// caller's types map into appropriate dom types
  -	for (int i = 0; i < names.length; i++) {
  +	for (i = 0; i < names.length; i++) {
   	    result[i + NTYPES] = (short)getGeneralizedType(names[i]);
   	    if (result[i + NTYPES] == ELEMENT)
   		result[i + NTYPES] = NO_TYPE;
  @@ -1757,15 +1759,16 @@
        * Get mapping from DOM namespace types to external namespace types
        */
       public short[] getNamespaceMapping(String[] namespaces) {
  +	int i;
   	final int nsLength = namespaces.length;
   	final int mappingLength = _nsNamesArray.length;
   	final short[] result = new short[mappingLength];
   
   	// Initialize all entries to -1
  -	for (int i=0; i<mappingLength; i++)
  +	for (i=0; i<mappingLength; i++)
   	    result[i] = (-1);
   
  -	for (int i=0; i<nsLength; i++) {
  +	for (i=0; i<nsLength; i++) {
   	    Integer type = (Integer)_nsIndex.get(namespaces[i]);
   	    if (type != null) {
   		result[type.intValue()] = (short)i;
  @@ -1779,10 +1782,11 @@
        * Get mapping from external namespace types to DOM namespace types
        */
       public short[] getReverseNamespaceMapping(String[] namespaces) {
  +	int i;
   	final int length = namespaces.length;
   	final short[] result = new short[length];
   
  -	for (int i=0; i<length; i++) {
  +	for (i=0; i<length; i++) {
   	    Integer type = (Integer)_nsIndex.get(namespaces[i]);
   	    if (type == null)
   		result[i] = -1;
  @@ -1916,7 +1920,11 @@
        */
       public String getNamespaceName(final int node) {
   	final int type = getNamespaceType(node);
  -	return(_nsNamesArray[type]);
  +	final String name = _nsNamesArray[type];
  +	if (name == null)
  +	    return(EMPTYSTRING);
  +	else
  +	    return(name);
       }
   
       /**
  @@ -2201,11 +2209,13 @@
       public void copy(final int node, TransletOutputHandler handler)
   	throws TransletException {
   
  +	int attr, child, col;
  +
   	if (node >= _treeNodeLimit) return;
   
   	switch(_type[node]) {
   	case ROOT:
  -	    for (int child = _offsetOrChild[node];
  +	    for (child = _offsetOrChild[node];
   		 child != NULL;
   		 child = _nextSibling[child]) {
   		copy(child, handler);
  @@ -2225,7 +2235,7 @@
   	    if (isElement(node)) {
   		final String name = getNodeName(node);
   		// Copy element name - start tag
  -		int col = name.lastIndexOf(':');
  +		col = name.lastIndexOf(':');
   		if (col > 0) {
   		    final String prefix = generateNamespacePrefix();
   		    handler.startElement(prefix+':'+name.substring(col+1));
  @@ -2236,7 +2246,7 @@
   		}
   
   		// Copy element attribute
  -		for (int attr = _lengthOrAttr[node];
  +		for (attr = _lengthOrAttr[node];
   		     attr != NULL;
   		     attr = _nextSibling[attr]) {
   		    final String aname = getNodeName(attr);
  @@ -2254,7 +2264,7 @@
   		// Copy element namespace declarations ???
   
   		// Copy element children
  -		for (int child = _offsetOrChild[node];
  +		for (child = _offsetOrChild[node];
   		     child != NULL;
   		     child = _nextSibling[child]) {
   		    copy(child, handler);
  @@ -2275,10 +2285,10 @@
   	throws TransletException {
   	final char[] text = _text;
   	final int start = _offsetOrChild[node];
  -	final int length = _lengthOrAttr[node];
   	int i = start + 1;
   	while (text[i] != ' ') ++i;
   
  +	final int length = _lengthOrAttr[node];
   	handler.processingInstruction(new String(text, start, i - start),
   				      new String(text, i + 1, length - i));
       }
  @@ -2671,25 +2681,29 @@
       	    final int node = nextAttributeNode();
   
   	    final String qname = attList.getQName(i);
  -	    final String uri = attList.getURI(i);
   	    final String localname = attList.getLocalName(i);
   	    final String value = attList.getValue(i);
  -
  -	    String name = null;
  -
  +	    
  +	    StringBuffer namebuf = new StringBuffer(EMPTYSTRING);
  +	    
   	    // Create the internal attribute node name (uri+@+localname)
   	    if (qname.startsWith(XML_STRING)) {
   		if (qname.startsWith(XMLSPACE_STRING))
   		    xmlSpaceDefine(attList.getValue(i), parent);
  -		name = "xml:@"+localname;
  +		namebuf.append("xml:");
   	    }
   	    else {
  -		if (uri.equals(EMPTYSTRING))
  -		    name = '@'+localname;
  -		else
  -		    name = uri+":@"+localname;
  +		final String uri = attList.getURI(i);
  +		if (!uri.equals(EMPTYSTRING)) {
  +		    namebuf.append(uri);
  +		    namebuf.append(':');
  +		}
   	    }
  +	    namebuf.append('@');
  +	    namebuf.append(localname);
   
  +	    String name = namebuf.toString();
  +	    
   	    // Get the index of the attribute node name (create new if non-ex).
   	    Integer obj = (Integer)_names.get(name);
   	    if (obj == null) {
  @@ -2952,14 +2966,17 @@
   	}
   	
   	private void shiftAttributes(final int shift) {
  +	    int i = 0;
  +	    int next = 0;
   	    final int limit = _currentAttributeNode;
   	    int lastParent = -1;
  -	    for (int i = 0; i < limit; i++) {
  +
  +	    for (i = 0; i < limit; i++) {
   		if (_parent2[i] != lastParent) {
   		    lastParent = _parent2[i];
   		    _lengthOrAttr[lastParent] = i + shift;
   		}
  -		final int next = _nextSibling2[i];
  +		next = _nextSibling2[i];
   		_nextSibling2[i] = next != 0 ? next + shift : 0;
   	    }
   	}
  
  
  
  1.3       +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/dom/DTDMonitor.java
  
  Index: DTDMonitor.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DTDMonitor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DTDMonitor.java	2001/05/01 13:16:20	1.2
  +++ DTDMonitor.java	2001/05/22 17:26:37	1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DTDMonitor.java,v 1.2 2001/05/01 13:16:20 morten Exp $
  + * @(#)$Id: DTDMonitor.java,v 1.3 2001/05/22 17:26:37 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -64,7 +64,6 @@
   package org.apache.xalan.xsltc.dom;
   
   import java.util.Enumeration;
  -import java.util.Hashtable;
   
   import org.xml.sax.XMLReader;
   import org.xml.sax.DTDHandler;
  @@ -75,6 +74,7 @@
   
   import org.apache.xalan.xsltc.*;
   import org.apache.xalan.xsltc.runtime.AbstractTranslet;
  +import org.apache.xalan.xsltc.runtime.Hashtable;
   
   final public class DTDMonitor implements DTDHandler, DeclHandler {
   
  
  
  
  1.2       +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java
  
  Index: KeyIndex.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- KeyIndex.java	2001/04/17 18:52:31	1.1
  +++ KeyIndex.java	2001/05/22 17:26:40	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: KeyIndex.java,v 1.1 2001/04/17 18:52:31 sboag Exp $
  + * @(#)$Id: KeyIndex.java,v 1.2 2001/05/22 17:26:40 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -63,11 +63,11 @@
   package org.apache.xalan.xsltc.dom;
   
   import java.util.Vector;
  -import java.util.Hashtable;
   import java.util.StringTokenizer;
   
   import org.apache.xalan.xsltc.DOM;
   import org.apache.xalan.xsltc.NodeIterator;
  +import org.apache.xalan.xsltc.runtime.Hashtable;
   
   public class KeyIndex implements NodeIterator {
       private Hashtable _index = new Hashtable();
  
  
  
  1.2       +2 -3      xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java
  
  Index: MultiDOM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MultiDOM.java	2001/04/17 18:52:32	1.1
  +++ MultiDOM.java	2001/05/22 17:26:43	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: MultiDOM.java,v 1.1 2001/04/17 18:52:32 sboag Exp $
  + * @(#)$Id: MultiDOM.java,v 1.2 2001/05/22 17:26:43 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -63,8 +63,6 @@
   
   package org.apache.xalan.xsltc.dom;
   
  -import java.util.Hashtable;
  -
   import org.w3c.dom.Node;
   import org.w3c.dom.NodeList;
   
  @@ -72,6 +70,7 @@
   import org.apache.xalan.xsltc.NodeIterator;
   import org.apache.xalan.xsltc.TransletOutputHandler;
   import org.apache.xalan.xsltc.TransletException;
  +import org.apache.xalan.xsltc.runtime.Hashtable;
   
   public final class MultiDOM implements DOM {
       private static final int NO_TYPE = DOM.FIRST_TYPE - 2;
  
  
  
  1.7       +127 -131  xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
  
  Index: AbstractTranslet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AbstractTranslet.java	2001/05/18 19:30:51	1.6
  +++ AbstractTranslet.java	2001/05/22 17:27:05	1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: AbstractTranslet.java,v 1.6 2001/05/18 19:30:51 tmiller Exp $
  + * @(#)$Id: AbstractTranslet.java,v 1.7 2001/05/22 17:27:05 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -65,7 +65,6 @@
   package org.apache.xalan.xsltc.runtime;
   
   import java.util.Vector;
  -import java.util.Hashtable;
   import java.util.Enumeration;
   import java.text.DecimalFormat;
   import java.text.DecimalFormatSymbols;
  @@ -291,6 +290,10 @@
   	return uri == null ? EMPTYSTRING : uri;
       }
   
  +    public final void setDTDMonitor(DTDMonitor monitor) {
  +	setUnparsedEntityURIs(monitor.getUnparsedEntityURIs());
  +    }
  +
       public final void setUnparsedEntityURIs(Hashtable table) {
   	if (_unparsedEntities == null)
   	    _unparsedEntities = table;
  @@ -403,6 +406,128 @@
        *  Transformer methods
        *********************************************************/
   
  +    public void transform(Source xmlsrc, Result outputTarget)
  +	throws TransformerException 
  +    {
  +	/********************
  +        doTransform( xmlsrc.getSystemId(), 
  +                    ((StreamResult)outputTarget).getOutputStream() ); 
  +	*******************************/
  +
  +	// try to get the encoding from Translet
  +	final Translet translet = (Translet)this;
  +	String encoding = translet.getOutputEncoding();
  +	if (encoding == null) encoding = "UTF-8";
  +
  +	// create a DefaultSAXOutputHandler
  +	DefaultSAXOutputHandler saxHandler = null;
  +	StreamResult target = (StreamResult)outputTarget;
  +	java.io.Writer writer = target.getWriter();
  +	java.io.OutputStream os = target.getOutputStream();
  +	String systemid = target.getSystemId();
  +	if (writer != null) {
  +	    // no constructor that takes encoding yet...
  +	    try {
  +		saxHandler = new DefaultSAXOutputHandler(writer); 
  +	    } catch (java.io.IOException e) {
  +		throw new TransformerException(
  +		"IOException creating DefaultSAXOutputHandler");
  +	    }
  +	} else if (os != null) {
  +	    try {
  +		saxHandler = new DefaultSAXOutputHandler(os, encoding); 
  +	    } catch (java.io.IOException e) {
  +		throw new TransformerException(
  +                     "IOException creating DefaultSAXOutputHandler");
  +	    }
  +	} else if (systemid != null) {
  +	    String filePrefix = new String("file:///");
  +	    if (systemid.startsWith(filePrefix)) {
  +		systemid = systemid.substring(filePrefix.length());
  +	    }
  +	    try {
  +		saxHandler = new DefaultSAXOutputHandler(
  +			((OutputStream)new FileOutputStream(systemid)), 
  +			encoding);
  +	    } catch (java.io.FileNotFoundException e) {
  +		throw new TransformerException(
  +			"Transform output target could not be opened.");
  +	    } catch (java.io.IOException e) {
  +		throw new TransformerException(
  +                   "Transform output target could not be opened.");
  +	    }
  +	}
  + 
  +	// finally do the transformation...
  +	doTransform(xmlsrc.getSystemId(), saxHandler, encoding);
  +    }
  + 
  +    private void doTransform(String xmlDocName, 
  +		     DefaultSAXOutputHandler saxHandler, String encoding) 
  +    {
  +	try {
  +	    final Translet translet = (Translet)this; // GTM added
  +
  +	    // Create a SAX parser and get the XMLReader object it uses
  +	    final SAXParserFactory factory = SAXParserFactory.newInstance();
  +	    final SAXParser parser = factory.newSAXParser();
  +	    final XMLReader reader = parser.getXMLReader();
  + 
  +	    // Set the DOM's DOM builder as the XMLReader's SAX2 content handler
  +	    final DOMImpl dom = new DOMImpl();
  +	    reader.setContentHandler(dom.getBuilder());
  +	    // Create a DTD monitor and pass it to the XMLReader object
  +	    final DTDMonitor dtdMonitor = new DTDMonitor();
  +	    dtdMonitor.handleDTD(reader);
  + 
  +	    dom.setDocumentURI(xmlDocName);
  +         /****************
  +             if (_uri)
  +                 reader.parse(xmlDocName);
  +             else
  +         *******************/
  +	    reader.parse("file:"+(new File(xmlDocName).getAbsolutePath()));
  +
  +	    // Set size of key/id indices
  +	    setIndexSize(dom.getSize());
  +	    // If there are any elements with ID attributes, build an index
  +	    dtdMonitor.buildIdIndex(dom, 0, this);
  + 
  +	    setDTDMonitor(dtdMonitor);
  + 
  +	    // Transform the document
  +	    TextOutput textOutput = new TextOutput(saxHandler, encoding);
  +	    translet.transform(dom, textOutput);
  +	    textOutput.flush();
  +	}
  +	catch (TransletException e) {
  +	    System.err.println("\nTranslet Error: " + e.getMessage());
  +	    System.exit(1);
  +	}
  +	catch (RuntimeException e) {
  +	    System.err.println("\nRuntime Error: " + e.getMessage());
  +	    System.exit(1);
  +	}
  +	catch (FileNotFoundException e) {
  +           //System.err.println("Error:File or URI '"+_fileName+"' not found.");
  +	    System.exit(1);
  +	}
  +	catch (MalformedURLException e) {
  +	    //System.err.println("Error: Invalid URI '"+_fileName+"'.");
  +	    System.exit(1);
  +	}
  +	catch (UnknownHostException e) {
  +	    //System.err.println("Error: Can't resolve URI specification '"+
  +	    //_fileName+"'.");
  +	    System.exit(1);
  +	}
  +	catch (Exception e) {
  +	    e.printStackTrace();
  +	    System.err.println("Error: internal error.");
  +	    System.exit(1);
  +	}
  +    }
  +
       public void clearParameters() {  
   	paramsStack.clear();
       }
  @@ -467,133 +592,4 @@
   	/*TBD*/
       }
   
  -    public void transform(Source xmlsrc, Result outputTarget)
  -        throws TransformerException 
  -    {
  -/********************
  -	doTransform( xmlsrc.getSystemId(), 
  -		     ((StreamResult)outputTarget).getOutputStream() ); 
  -*******************************/
  -
  -	// try to get the encoding from Translet
  -	final Translet translet = (Translet)this;
  -	String encoding = translet.getOutputEncoding();
  -	if (encoding == null) encoding = "UTF-8";
  -
  -
  -	// create a DefaultSAXOutputHandler
  -	DefaultSAXOutputHandler saxHandler = null;
  -	StreamResult target = (StreamResult)outputTarget;	
  -	java.io.Writer writer = target.getWriter();
  -	java.io.OutputStream os = target.getOutputStream();
  -	String systemid = target.getSystemId();
  -	if (writer != null) {
  -	    // no constructor that takes encoding yet...
  -	    try {
  -	        saxHandler = new DefaultSAXOutputHandler(writer); 
  -	    } catch (java.io.IOException e) {
  -	        throw new TransformerException(
  -                    "IOException creating DefaultSAXOutputHandler");
  -	    }
  -	} else if (os != null) {
  -	    try {
  -	        saxHandler = new DefaultSAXOutputHandler(os, encoding); 
  -	    } catch (java.io.IOException e) {
  -                throw new TransformerException(
  -                    "IOException creating DefaultSAXOutputHandler");
  -            }
  -	} else if (systemid != null) {
  -	    String filePrefix = new String("file:///");
  -	    if (systemid.startsWith(filePrefix)) {
  -	        systemid = systemid.substring(filePrefix.length());
  -	    }
  -	    try {
  -                saxHandler = new DefaultSAXOutputHandler(
  -		    ((OutputStream)new FileOutputStream(systemid)), 
  -		    encoding);
  -	    } catch (java.io.FileNotFoundException e) {
  -	        throw new TransformerException(
  -		    "Transform output target could not be opened.");
  -	    } catch (java.io.IOException e) {
  -	        throw new TransformerException(
  -		    "Transform output target could not be opened.");
  -	    }
  -	}
  -
  -	// finally do the transformation...	
  -	doTransform(xmlsrc.getSystemId(), saxHandler, encoding);
  -    }
  -
  -    private void doTransform(String xmlDocName, 
  -	DefaultSAXOutputHandler saxHandler, String encoding) 
  -    {
  -        try {
  -            final Translet translet = (Translet)this; // GTM added
  -
  -            // Create a SAX parser and get the XMLReader object it uses
  -            final SAXParserFactory factory = SAXParserFactory.newInstance();
  -            final SAXParser parser = factory.newSAXParser();
  -            final XMLReader reader = parser.getXMLReader();
  -
  -            // Set the DOM's DOM builder as the XMLReader's SAX2 content handler
  -            final DOMImpl dom = new DOMImpl();
  -            reader.setContentHandler(dom.getBuilder());
  -            // Create a DTD monitor and pass it to the XMLReader object
  -            final DTDMonitor dtdMonitor = new DTDMonitor();
  -            dtdMonitor.handleDTD(reader);
  -
  -            dom.setDocumentURI(xmlDocName);
  -        /****************
  -            if (_uri)
  -                reader.parse(xmlDocName);
  -            else
  -        *******************/
  -            reader.parse("file:"+(new File(xmlDocName).getAbsolutePath()));
  -           
  -            // Set size of key/id indices
  -            setIndexSize(dom.getSize());
  -            // If there are any elements with ID attributes, build an index
  -            dtdMonitor.buildIdIndex(dom, 0, this);
  -
  -            setUnparsedEntityURIs(dtdMonitor.getUnparsedEntityURIs());
  -
  -            // Transform the document
  -            //String encoding = translet.getOutputEncoding();
  -            //if (encoding == null) encoding = "UTF-8";
  -
  -            //TextOutput textOutput = new TextOutput(System.out, encoding);
  -            //DefaultSAXOutputHandler saxHandler = new
  -             //   DefaultSAXOutputHandler(ostream, encoding);
  -            TextOutput textOutput = new TextOutput(saxHandler, encoding);
  -            translet.transform(dom, textOutput);
  -            textOutput.flush();
  -
  -        }
  -        catch (TransletException e) {
  -            System.err.println("\nTranslet Error: " + e.getMessage());
  -            System.exit(1);
  -        }
  -        catch (RuntimeException e) {
  -            System.err.println("\nRuntime Error: " + e.getMessage());
  -            System.exit(1);
  -        }
  -        catch (FileNotFoundException e) {
  -           //System.err.println("Error:File or URI '"+_fileName+"' not found.");
  -            System.exit(1);
  -        }
  -        catch (MalformedURLException e) {
  -            //System.err.println("Error: Invalid URI '"+_fileName+"'.");
  -            System.exit(1);
  -        }
  -        catch (UnknownHostException e) {
  -            //System.err.println("Error: Can't resolve URI specification '"+
  -                               //_fileName+"'.");
  -            System.exit(1);
  -        }
  -        catch (Exception e) {
  -            e.printStackTrace();
  -            System.err.println("Error: internal error.");
  -            System.exit(1);
  -        }
  -    }
   }
  
  
  
  1.3       +1 -2      xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AttributeList.java
  
  Index: AttributeList.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AttributeList.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AttributeList.java	2001/05/01 13:16:22	1.2
  +++ AttributeList.java	2001/05/22 17:27:11	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: AttributeList.java,v 1.2 2001/05/01 13:16:22 morten Exp $
  + * $Id: AttributeList.java,v 1.3 2001/05/22 17:27:11 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -66,7 +66,6 @@
   
   import java.util.Vector;
   import java.util.Enumeration;
  -import java.util.Hashtable;
   
   public class AttributeList implements org.xml.sax.Attributes {
   
  
  
  
  1.2       +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
  
  Index: BasisLibrary.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BasisLibrary.java	2001/04/17 18:52:43	1.1
  +++ BasisLibrary.java	2001/05/22 17:27:13	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: BasisLibrary.java,v 1.1 2001/04/17 18:52:43 sboag Exp $
  + * @(#)$Id: BasisLibrary.java,v 1.2 2001/05/22 17:27:13 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -64,7 +64,7 @@
   
   package org.apache.xalan.xsltc.runtime;
   
  -import java.util.Hashtable;
  +//import java.util.Hashtable;
   import java.text.DecimalFormat;
   import java.text.DecimalFormatSymbols;
   import java.text.FieldPosition;
  
  
  
  1.5       +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/runtime/DefaultRun.java
  
  Index: DefaultRun.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/DefaultRun.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultRun.java	2001/05/15 19:36:12	1.4
  +++ DefaultRun.java	2001/05/22 17:27:16	1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DefaultRun.java,v 1.4 2001/05/15 19:36:12 amiro Exp $
  + * @(#)$Id: DefaultRun.java,v 1.5 2001/05/22 17:27:16 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -148,7 +148,7 @@
   	    // If there are any elements with ID attributes, build an index
   	    dtdMonitor.buildIdIndex(dom, 0, _translet);
   
  -	    _translet.setUnparsedEntityURIs(dtdMonitor.getUnparsedEntityURIs());
  +	    _translet.setDTDMonitor(dtdMonitor);
   
   	    // Pass global parameters
   	    int n = _params.size();
  
  
  
  1.4       +11 -12    xml-xalan/java/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
  
  Index: DefaultSAXOutputHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultSAXOutputHandler.java	2001/05/17 14:27:40	1.3
  +++ DefaultSAXOutputHandler.java	2001/05/22 17:27:21	1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DefaultSAXOutputHandler.java,v 1.3 2001/05/17 14:27:40 tmiller Exp $
  + * @(#)$Id: DefaultSAXOutputHandler.java,v 1.4 2001/05/22 17:27:21 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -69,7 +69,6 @@
   import java.io.OutputStream;
   import java.io.OutputStreamWriter;
   import java.io.BufferedWriter;
  -import java.util.Hashtable;
   
   import org.xml.sax.ContentHandler;
   import org.xml.sax.Locator;
  @@ -304,16 +303,16 @@
                   if ((_indent) && (_indentNextEndTag)) indent(false);
                   char[] endTag = (char[])_endTags.get(elementName);
                   if (endTag == null) {
  -		    // CHANGED OUTPUT LAYOUT
  -		    /*
  -		    if (_outputType == TextOutput.HTML) { 
  -                        endTag = ("</"+elementName+">\n").toCharArray();
  -		    } else {
  -			// works for XML, TEXT
  -                        endTag = ("</"+elementName+">").toCharArray();
  -		    }
  -		    */
  -		    endTag = ("</"+elementName+">\n").toCharArray();
  +		    // We dont' want to concatenate String objects!!!!
  +		    // endTag = ("</"+elementName+">\n").toCharArray();
  +		    final int len = elementName.length();
  +		    final char[] src = elementName.toCharArray();
  +		    endTag = new char[len+4];
  +		    System.arraycopy(src, 0, endTag, 2, len);
  +		    endTag[0] = '<';
  +		    endTag[1] = '/';
  +		    endTag[len+2] = '>';
  +		    endTag[len+3] = '\n';
                       _endTags.put(elementName,endTag);
                   }
                   _writer.write(endTag);
  
  
  
  1.7       +18 -12    xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TextOutput.java
  
  Index: TextOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TextOutput.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TextOutput.java	2001/05/21 19:35:43	1.6
  +++ TextOutput.java	2001/05/22 17:27:28	1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: TextOutput.java,v 1.6 2001/05/21 19:35:43 tmiller Exp $
  + * @(#)$Id: TextOutput.java,v 1.7 2001/05/22 17:27:28 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -65,7 +65,6 @@
   package org.apache.xalan.xsltc.runtime;
   
   import java.io.*;
  -import java.util.Hashtable;
   import java.util.Stack;
   
   import org.apache.xalan.xsltc.*;
  @@ -234,7 +233,7 @@
   		// Final check to assure that the element is within a namespace
   		// that has been declared (all declarations for this element
   		// should have been processed at this point).
  -		int col = _elementName.indexOf(':');
  +		int col = _elementName.lastIndexOf(':');
   		if (col > 0) {
   		    final String prefix = _elementName.substring(0,col);
   		    final String localname = _elementName.substring(col+1);
  @@ -393,13 +392,14 @@
   
   	    int limit = off + len;
   	    int offset = off;
  +	    int i;
   
               // Take special precautions if within a CDATA section. If we
               // encounter the sequence ']]>' within the CDATA, we need to
               // break the section in two and leave the ']]' at the end of
               // the first CDATA and '>' at the beginning of the next.
               if (_cdataTagOpen && len>2) {
  -                for (int i = off; i < limit-2; i++) {
  +                for (i = off; i < limit-2; i++) {
                       if (ch[i] == ']' && ch[i+1] == ']' && ch[i+2] == '>') {
                           _saxHandler.characters(ch, offset, i - offset);
                           characters(CNTCDATA);
  @@ -414,7 +414,7 @@
   	    // Output escaped characters if required. Non-ASCII characters
               // within HTML attributes should _NOT_ be escaped.
   	    else if (_escapeChars) {
  -                for (int i = off; i < limit; i++) {
  +                for (i = off; i < limit; i++) {
                       switch (ch[i]) {
                       case '&':
                           _saxHandler.characters(ch, offset, i - offset);
  @@ -507,12 +507,13 @@
        */
       private String escapeChars(String value) {
   
  -	StringBuffer buf = new StringBuffer();
  +	int i;
   	char[] ch = value.toCharArray();
  -	int offset = 0;
   	int limit = ch.length;
  +	int offset = 0;
  +	StringBuffer buf = new StringBuffer();
   	
  -	for (int i = 0; i < limit; i++) {
  +	for (i = 0; i < limit; i++) {
   	    switch (ch[i]) {
   	    case '&':
   		buf.append(ch, offset, i - offset);
  @@ -559,10 +560,15 @@
   
   	if (_startTagOpen) {
   	    // Intercept namespace declarations and handle them separately
  -	    if (name.startsWith("xmlns"))
  -		namespace(name.substring(6),value);
  -	    else
  +	    if (name.startsWith("xmlns")) {
  +		if (name.length() == 5)
  +		    namespace(EMPTYSTRING,value);
  +		else
  +		    namespace(name.substring(6),value);
  +	    }
  +	    else {
   		_attributes.add(name,escapeChars(value));
  +	    }
   	}
   	else if (_cdataTagOpen) {
   	    throw new TransletException("attribute '"+name+"' within CDATA");
  @@ -754,7 +760,7 @@
        * returns a strig with the expanded QName on the format uri:local-name.
        */
       private String expandQName(String withPrefix) {
  -	int col = withPrefix.indexOf(':');
  +	int col = withPrefix.lastIndexOf(':');
   	if (col == -1) return(withPrefix);
   
   	final String prefix = withPrefix.substring(0,col);
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/xsltc/runtime/Hashtable.java
  
  Index: Hashtable.java
  ===================================================================
  /*
   * @(#)$Id: Hashtable.java,v 1.1 2001/05/22 17:27:27 morten Exp $
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Sun
   * Microsystems., http://www.sun.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * @author Morten Jorgensen
   *
   */
  
  package org.apache.xalan.xsltc.runtime;
  
  import java.io.*;
  import java.util.Enumeration;
  
  /**
   * IMPORTANT NOTE:
   * This code was taken from Sun's Java1.1 JDK java.util.HashTable.java
   * All "synchronized" keywords and some methods we do not need have been 
   * all been removed.
   */
  
  /**
   * Object that wraps entries in the hash-table
   */
  class HashtableEntry {
      int hash;
      Object key;
      Object value;
      HashtableEntry next;
  
      protected Object clone() {
  	HashtableEntry entry = new HashtableEntry();
  	entry.hash = hash;
  	entry.key = key;
  	entry.value = value;
  	entry.next = (next != null) ? (HashtableEntry)next.clone() : null;
  	return entry;
      }
  }
  
  /**
   * The main hash-table implementation
   */
  public class Hashtable {
  
      private transient HashtableEntry table[]; // hash-table entries
      private transient int count;              // number of entries
      private int threshold;                    // current size of hash-tabke
      private float loadFactor;                 // load factor
  
      /**
       * Constructs a new, empty hashtable with the specified initial 
       * capacity and the specified load factor. 
       */
      public Hashtable(int initialCapacity, float loadFactor) {
  	if (initialCapacity <= 0) initialCapacity = 11;
  	if (loadFactor <= 0.0) loadFactor = 0.75f;
  	this.loadFactor = loadFactor;
  	table = new HashtableEntry[initialCapacity];
  	threshold = (int)(initialCapacity * loadFactor);
      }
  
      /**
       * Constructs a new, empty hashtable with the specified initial capacity
       * and default load factor.
       */
      public Hashtable(int initialCapacity) {
  	this(initialCapacity, 0.75f);
      }
  
      /**
       * Constructs a new, empty hashtable with a default capacity and load
       * factor. 
       */
      public Hashtable() {
  	this(101, 0.75f);
      }
  
      /**
       * Returns the number of keys in this hashtable.
       */
      public int size() {
  	return count;
      }
  
      /**
       * Tests if this hashtable maps no keys to values.
       */
      public boolean isEmpty() {
  	return count == 0;
      }
  
      /**
       * Returns an enumeration of the keys in this hashtable.
       */
      public Enumeration keys() {
  	return new HashtableEnumerator(table, true);
      }
  
      /**
       * Returns an enumeration of the values in this hashtable.
       * Use the Enumeration methods on the returned object to fetch the elements
       * sequentially.
       */
      public Enumeration elements() {
  	return new HashtableEnumerator(table, false);
      }
  
      /**
       * Tests if some key maps into the specified value in this hashtable.
       * This operation is more expensive than the <code>containsKey</code>
       * method.
       */
      public boolean contains(Object value) {
  
  	if (value == null) throw new NullPointerException();
  
  	int i;
  	HashtableEntry e;
  	HashtableEntry tab[] = table;
  
  	for (i = tab.length ; i-- > 0 ;) {
  	    for (e = tab[i] ; e != null ; e = e.next) {
  		if (e.value.equals(value)) {
  		    return true;
  		}
  	    }
  	}
  	return false;
      }
  
      /**
       * Tests if the specified object is a key in this hashtable.
       */
      public boolean containsKey(Object key) {
  	HashtableEntry e;
  	HashtableEntry tab[] = table;
  	int hash = key.hashCode();
  	int index = (hash & 0x7FFFFFFF) % tab.length;
  
  	for (e = tab[index] ; e != null ; e = e.next)
  	    if ((e.hash == hash) && e.key.equals(key))
  		return true;
  
  	return false;
      }
  
      /**
       * Returns the value to which the specified key is mapped in this hashtable.
       */
      public Object get(Object key) {
  	HashtableEntry e;
  	HashtableEntry tab[] = table;
  	int hash = key.hashCode();
  	int index = (hash & 0x7FFFFFFF) % tab.length;
  
  	for (e = tab[index] ; e != null ; e = e.next) 
  	    if ((e.hash == hash) && e.key.equals(key)) 
  		return e.value;
  
  	return null;
      }
  
      /**
       * Rehashes the contents of the hashtable into a hashtable with a 
       * larger capacity. This method is called automatically when the 
       * number of keys in the hashtable exceeds this hashtable's capacity 
       * and load factor. 
       */
      protected void rehash() {
  	HashtableEntry e, old;
  	int i, index;
  	int oldCapacity = table.length;
  	HashtableEntry oldTable[] = table;
  
  	int newCapacity = oldCapacity * 2 + 1;
  	HashtableEntry newTable[] = new HashtableEntry[newCapacity];
  
  	threshold = (int)(newCapacity * loadFactor);
  	table = newTable;
  
  	for (i = oldCapacity ; i-- > 0 ;) {
  	    for (old = oldTable[i] ; old != null ; ) {
  		e = old;
  		old = old.next;
  		index = (e.hash & 0x7FFFFFFF) % newCapacity;
  		e.next = newTable[index];
  		newTable[index] = e;
  	    }
  	}
      }
  
      /**
       * Maps the specified <code>key</code> to the specified 
       * <code>value</code> in this hashtable. Neither the key nor the 
       * value can be <code>null</code>. 
       * <p>
       * The value can be retrieved by calling the <code>get</code> method 
       * with a key that is equal to the original key. 
       */
      public Object put(Object key, Object value) {
  	// Make sure the value is not null
  	if (value == null) throw new NullPointerException();
  
  	// Makes sure the key is not already in the hashtable.
  	HashtableEntry e;
  	HashtableEntry tab[] = table;
  	int hash = key.hashCode();
  	int index = (hash & 0x7FFFFFFF) % tab.length;
  
  	for (e = tab[index] ; e != null ; e = e.next) {
  	    if ((e.hash == hash) && e.key.equals(key)) {
  		Object old = e.value;
  		e.value = value;
  		return old;
  	    }
  	}
  
  	// Rehash the table if the threshold is exceeded
  	if (count >= threshold) {
  	    rehash();
  	    return put(key, value);
  	} 
  
  	// Creates the new entry.
  	e = new HashtableEntry();
  	e.hash = hash;
  	e.key = key;
  	e.value = value;
  	e.next = tab[index];
  	tab[index] = e;
  	count++;
  	return null;
      }
  
      /**
       * Removes the key (and its corresponding value) from this 
       * hashtable. This method does nothing if the key is not in the hashtable.
       */
      public Object remove(Object key) {
  	HashtableEntry e, prev;
  	HashtableEntry tab[] = table;
  	int hash = key.hashCode();
  	int index = (hash & 0x7FFFFFFF) % tab.length;
  	for (e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
  	    if ((e.hash == hash) && e.key.equals(key)) {
  		if (prev != null)
  		    prev.next = e.next;
  		else
  		    tab[index] = e.next;
  		count--;
  		return e.value;
  	    }
  	}
  	return null;
      }
  
      /**
       * Clears this hashtable so that it contains no keys. 
       */
      public void clear() {
  	HashtableEntry tab[] = table;
  	for (int index = tab.length; --index >= 0; )
  	    tab[index] = null;
  	count = 0;
      }
  
      /**
       * Returns a rather long string representation of this hashtable.
       * Handy for debugging - leave it here!!!
       */
      public String toString() {
  	int i;
  	int max = size() - 1;
  	StringBuffer buf = new StringBuffer();
  	Enumeration k = keys();
  	Enumeration e = elements();
  	buf.append("{");
  
  	for (i = 0; i <= max; i++) {
  	    String s1 = k.nextElement().toString();
  	    String s2 = e.nextElement().toString();
  	    buf.append(s1 + "=" + s2);
  	    if (i < max) buf.append(", ");
  	}
  	buf.append("}");
  	return buf.toString();
      }
  
      /**
       * A hashtable enumerator class.  This class should remain opaque 
       * to the client. It will use the Enumeration interface.
       */
      class HashtableEnumerator implements Enumeration {
  	boolean keys;
  	int index;
  	HashtableEntry table[];
  	HashtableEntry entry;
  
  	HashtableEnumerator(HashtableEntry table[], boolean keys) {
  	    this.table = table;
  	    this.keys = keys;
  	    this.index = table.length;
  	}
  	
  	public boolean hasMoreElements() {
  	    if (entry != null) {
  		return true;
  	    }
  	    while (index-- > 0) {
  		if ((entry = table[index]) != null) {
  		    return true;
  		}
  	    }
  	    return false;
  	}
  
  	public Object nextElement() {
  	    if (entry == null) {
  		while ((index-- > 0) && ((entry = table[index]) == null));
  	    }
  	    if (entry != null) {
  		HashtableEntry e = entry;
  		entry = e.next;
  		return keys ? e.key : e.value;
  	    }
  	    return null;
  	}
      }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org