You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by tm...@apache.org on 2002/05/21 00:15:33 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output SAXHTMLOutput.java SAXOutput.java SAXXMLOutput.java

tmiller     02/05/20 15:15:33

  Modified:    java/src/org/apache/xalan/xsltc/runtime/output
                        SAXHTMLOutput.java SAXOutput.java SAXXMLOutput.java
  Log:
  updated new code, on-going development
  
  Revision  Changes    Path
  1.2       +100 -42   xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java
  
  Index: SAXHTMLOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SAXHTMLOutput.java	17 May 2002 16:52:56 -0000	1.1
  +++ SAXHTMLOutput.java	20 May 2002 22:15:33 -0000	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SAXHTMLOutput.java,v 1.1 2002/05/17 16:52:56 tmiller Exp $
  + * @(#)$Id: SAXHTMLOutput.java,v 1.2 2002/05/20 22:15:33 tmiller Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -68,28 +68,30 @@
   import org.xml.sax.ext.LexicalHandler;
   import org.apache.xalan.xsltc.TransletException;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
  +import org.apache.xalan.xsltc.runtime.AttributeList;
   
   
   public class SAXHTMLOutput extends SAXOutput  { 
  -   private boolean   _headTagOpen = false;
  +    private boolean   _headTagOpen = false;
  +    private String _mediaType = "text/html";
   
  -   public SAXHTMLOutput(ContentHandler handler, String encoding) {
  +    public SAXHTMLOutput(ContentHandler handler, String encoding) {
   	super(handler, encoding);
  -   }
  +    }
   
  -   public SAXHTMLOutput(ContentHandler handler, LexicalHandler lex, 
  +    public SAXHTMLOutput(ContentHandler handler, LexicalHandler lex, 
   	String encoding)
  -   {
  +    {
   	super(handler, lex, encoding);
  -   }
  +    }
   
   
  -   public void startElement(String elementName) throws TransletException {
  -   }
  +    public void startElement(String elementName) throws TransletException {
  +    }
   
  -   public void attribute(String name, final String value) 
  +    public void attribute(String name, final String value) 
   	throws TransletException
  -   {
  +    {
   	final String patchedName = patchQName(name);
   	final String localName = getLocalName(patchedName);
   	final int index = _attributes.getIndex(name); 
  @@ -97,42 +99,98 @@
   	if (!_startTagOpen) {
               BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
           }
  -	/*
  -         * The following is an attempt to escape an URL stored in a href
  -         * attribute of HTML output. Normally URLs should be encoded at
  -         * the time they are created, since escaping or unescaping a
  -         * completed URI might change its semantics. We limit or escaping
  -         * to include space characters only - and nothing else. This is for
  -         * two reasons: (1) performance and (2) we want to make sure that
  -         * we do not change the meaning of the URL.
  -         */
  -        final String tmp = name.toLowerCase();
  -        if (tmp.equals("href") || tmp.equals("src") || 
  -            tmp.equals("cite")) 
  -        {
  -		/************
  -            if (index >= 0) {
  -                _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING, 
  -                    name, "CDATA", quickAndDirtyUrlEncode(escapeAttr(value)));
  -            }
  -            else {
  -                _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING, name, 
  -                    "CDATA", quickAndDirtyUrlEncode(escapeAttr(value)));
  -            }
  -		**************/
  +        if (index >= 0) {
  +            _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING,
  +                    name, "CDATA", value);
           }
           else {
  -            if (index >= 0) {
  -                _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING,
  -                    name, "CDATA", value);
  -            }
  -            else {
  -                _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING,
  -                    name, "CDATA", value);
  +            _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING,
  +                name, "CDATA", value);
  +        }
  +    }
  +
  +    /**
  +    * Send characters to the output document
  +    */
  +    public void characters(char[] ch, int off, int len)
  +        throws TransletException 
  +    {
  +	try {
  +            // Close any open start tag
  +            if (_startTagOpen) closeStartTag();
  +            _saxHandler.characters(ch, off, len);
  +        }
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +    /**
  +     * This method is called when all the data needed for a call to the
  +     * SAX handler's startElement() method has been gathered.
  +     */
  +    public void closeStartTag() throws TransletException {
  +        try {
  +            _startTagOpen = false;
  +
  +            // Now is time to send the startElement event
  +            _saxHandler.startElement(null, _elementName, _elementName, 
  +		_attributes);
  +
  +            // Insert <META> tag directly after <HEAD> element in HTML output
  +            if (_headTagOpen) {
  +                emitHeader();
  +                _headTagOpen = false;
               }
           }
  -   }
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +
  +    /**
  +     * Emit header through the SAX handler
  +     */
  +    private void emitHeader() throws SAXException {
  +        AttributeList attrs = new AttributeList();
  +        attrs.add("http-equiv", "Content-Type");
  +        attrs.add("content", _mediaType+"; charset="+_encoding);
  +        _saxHandler.startElement(EMPTYSTRING, EMPTYSTRING, "meta", attrs);
  +        _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, "meta");
  +    }
   
      
  +    /**
  +     * End an element or CDATA section in the output document
  +     */
  +    public void endElement(String elementName) throws TransletException {
  +        try {
  +            // Close any open element
  +            if (_startTagOpen) closeStartTag();
  +            _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING,
  +                (String)(_qnameStack.pop()));
  +        } catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +
  +    }
   
  +    private void initNamespaces() { 
  +	//empty 
  +    }
  +
  +    private String lookupNamespace(String prefix) { 
  +	return null;	// no-op	
  +    }
  +
  +    private void popNamespace(String prefix) throws SAXException {
  +	//empty
  +    }
  +
  +    private String getNamespaceURI(String qname, boolean isElement)
  +        throws TransletException
  +    {
  +	return null;	// no-op	
  +    } 
   }
  
  
  
  1.2       +49 -49    xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXOutput.java
  
  Index: SAXOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXOutput.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SAXOutput.java	17 May 2002 16:52:56 -0000	1.1
  +++ SAXOutput.java	20 May 2002 22:15:33 -0000	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SAXOutput.java,v 1.1 2002/05/17 16:52:56 tmiller Exp $
  + * @(#)$Id: SAXOutput.java,v 1.2 2002/05/20 22:15:33 tmiller Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -63,6 +63,7 @@
   
   package org.apache.xalan.xsltc.runtime.output;
   
  +import java.util.Stack;
   import org.xml.sax.ContentHandler;
   import org.xml.sax.SAXException;
   import org.xml.sax.ext.LexicalHandler;
  @@ -72,82 +73,79 @@
   import org.apache.xalan.xsltc.runtime.DefaultSAXOutputHandler;
   
   public class SAXOutput extends OutputBase implements Constants { 
  -   protected ContentHandler _saxHandler;
  -   protected LexicalHandler _lexicalHandler;
  -   protected boolean _startTagOpen = false;
  -   protected String  _encoding = null; 
  -   protected AttributesImpl _attributes = new AttributesImpl();
  +    protected ContentHandler _saxHandler;
  +    protected LexicalHandler _lexHandler;
  +    protected boolean        _startTagOpen = false;
  +    protected AttributesImpl _attributes = new AttributesImpl();
  +    protected String	     _elementName = null;
  +
  +    // parameters set by <xsl:output> element, or by set/getOutputProperty()
  +    protected String    _encoding = null; 
  +    protected String    _doctypeSystem = null;
  +    protected String    _doctypePublic = null;
  + 
  +    // The top of this stack contains the QName of the currently open element
  +    protected Stack     _qnameStack;
   
   
  -   public SAXOutput(ContentHandler handler, String encoding) {
  +    public SAXOutput(ContentHandler handler, String encoding) {
   	_saxHandler = handler;
   	_encoding = encoding;
  -   } 
  +    } 
   
  -   public SAXOutput(ContentHandler hdler, LexicalHandler lex, String encoding){
  +    public SAXOutput(ContentHandler hdler, LexicalHandler lex, String encoding){
   	_saxHandler = hdler;
  -	_lexicalHandler = lex;
  +	_lexHandler = lex;
   	_encoding = encoding;
  -   } 
  +    } 
   
  -   public void startDocument() throws TransletException {
  +    public void startDocument() throws TransletException {
   	try {
   	    _saxHandler.startDocument();
   	} catch (SAXException e) {
   	    throw new TransletException(e);
   	}
  -   }
  +    }
   
  -   public void endDocument() throws TransletException {
  +    public void endDocument() throws TransletException {
   	try {
   	    _saxHandler.endDocument();
   	} catch (SAXException e) {
               throw new TransletException(e);
           }
  -   }
  -
  -   // ContentHandler: startElement(String namespace, String lname, 
  -   //    String qname, Attributes)
  -   public void startElement(String elementName) throws TransletException {
  -	try {
  -	    _saxHandler.startElement(EMPTYSTRING, EMPTYSTRING, 
  -		elementName, _attributes);
  -	} catch (SAXException e) {
  -            throw new TransletException(e);
  -        }
  -   }
  +    }
   
  -   // ContentHandler: endElement(String namespace, String lname, String qname)
  -   public void endElement(String elementName) throws TransletException {
  -	try {
  -	    _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, elementName);
  -	} catch (SAXException e) {
  -            throw new TransletException(e);
  -        }
  -   }
   
  -   public void characters(String  characters)
  +    public void characters(String  characters)
          throws TransletException
  -   {
  +    {
   	try {
   	    _saxHandler.characters(characters.toCharArray(), 0, 
   		characters.length());	
   	} catch (SAXException e) {
               throw new TransletException(e);
           }
  -   }
  +    }
  +
  +    /**
  +     * Set the output document system/public identifiers
  +     */
  +    public void setDoctype(String system, String pub) {
  +        _doctypeSystem = system;
  +        _doctypePublic = pub;
  +    }
  +
   
  -   public void characters(char[] characters, int offset, int length)
  -       throws TransletException
  -   {
  -	try {
  -	    _saxHandler.characters(characters, offset, length);
  -	} catch (SAXException e) {
  -            throw new TransletException(e);
  -        }
  -   }
   
  -   protected static String patchQName(String qname) throws TransletException {
  +   /**
  +     * TODO: This method is a HACK! Since XSLTC does not have access to the
  +     * XML file, it sometimes generates a NS prefix of the form "ns?" for
  +     * an attribute. If at runtime, when the qname of the attribute is
  +     * known, another prefix is specified for the attribute, then we can get
  +     * a qname of the form "ns?:otherprefix:name". This function patches the
  +     * qname by simply ignoring "otherprefix".
  +     */ 
  +    protected static String patchQName(String qname) throws TransletException {
           final int lastColon = qname.lastIndexOf(':');
           if (lastColon > 0) {
               final int firstColon = qname.indexOf(':');
  @@ -159,12 +157,14 @@
           return qname;
       }
   
  +    /**
  +     * returns the local name of a qualified name. If the name has no prefix
  +     * then return null.
  +     */
       protected static String getLocalName(String qname) throws 
   	TransletException 
       {
           final int col = qname.lastIndexOf(':');
           return (col > 0) ? qname.substring(col + 1) : null;
       }
  -
  -
   }
  
  
  
  1.2       +328 -7    xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java
  
  Index: SAXXMLOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SAXXMLOutput.java	17 May 2002 16:52:56 -0000	1.1
  +++ SAXXMLOutput.java	20 May 2002 22:15:33 -0000	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SAXXMLOutput.java,v 1.1 2002/05/17 16:52:56 tmiller Exp $
  + * @(#)$Id: SAXXMLOutput.java,v 1.2 2002/05/20 22:15:33 tmiller Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -63,20 +63,341 @@
   
   package org.apache.xalan.xsltc.runtime.output;
   
  +import java.util.Stack;
  +
   import org.xml.sax.ContentHandler;
   import org.xml.sax.ext.LexicalHandler;
  +import org.apache.xalan.xsltc.TransletException;
  +import org.apache.xalan.xsltc.runtime.Hashtable;
  +import org.xml.sax.SAXException;
  +import org.apache.xalan.xsltc.runtime.BasisLibrary;
  +import org.apache.xalan.xsltc.runtime.DefaultSAXOutputHandler;
   
   public class SAXXMLOutput extends SAXOutput  {
   
  -   public SAXXMLOutput(ContentHandler handler, String encoding) {
  -        super(handler, encoding);
  -   }
  +    // Each entry (prefix) in this hashtable points to a Stack of URIs
  +    private Hashtable _namespaces;
  +    // The top of this stack contains an id of the element that last declared
  +    // a namespace. Used to ensure prefix/uri map scopes are closed correctly
  +    private Stack     _nodeStack;
  +    // The top of this stack is the prefix that was last mapped to an URI
  +    private Stack     _prefixStack;
  +
  +
  +    // Contains all elements that should be output as CDATA sections
  +    private Hashtable _cdata = null;
  +
  +    private boolean   _cdataTagOpen = false;
  +    // The top of this stack contains the element id of the last element whose
  +    // contents should be output as CDATA sections.
  +    private Stack     _cdataStack;
  +
  +    // Holds the current tree depth (see startElement() and endElement()).
  +    private int _depth = 0;
  +
  +    // The top of this stack contains the QName of the currently open element
  +    private Stack     _qnameStack;
   
  -   public SAXXMLOutput(ContentHandler handler, LexicalHandler lex, 
  +    private static final char[] BEGCDATA = "<![CDATA[".toCharArray();
  +    private static final char[] ENDCDATA = "]]>".toCharArray();
  +    private static final char[] CNTCDATA = "]]]]><![CDATA[>".toCharArray();
  +    
  +
  +    public SAXXMLOutput(ContentHandler handler, String encoding) {
  +    	super(handler, encoding);
  +    }
  +
  +    public SAXXMLOutput(ContentHandler handler, LexicalHandler lex, 
           String encoding)
  -   {
  +    {
           super(handler, lex, encoding);
  -   }
  +    }
  +
  +    public void endDocument() throws TransletException {
  +	try {
  +	    // Close any open start tag
  +            if (_startTagOpen) closeStartTag();
  +            if (_cdataTagOpen) closeCDATA();
  +
  +            // Close output document
  +            _saxHandler.endDocument();
  +        } catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +    /**
  +     * This method is called when all the data needed for a call to the
  +     * SAX handler's startElement() method has been gathered.
  +     */
  +    public void closeStartTag() throws TransletException {
  +        try {
  +            _startTagOpen = false;
  +
  +            // Now is time to send the startElement event
  +            _saxHandler.startElement(getNamespaceURI(_elementName, true),
  +                getLocalName(_elementName), _elementName, _attributes);
  +        }
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +    /**
  +     * Returns the URI of an element or attribute. Note that default namespaces
  +     * do not apply directly to attributes.
  +     */
  +    private String getNamespaceURI(String qname, boolean isElement)
  +        throws TransletException
  +    {
  +        String uri = EMPTYSTRING;
  +        int col = qname.lastIndexOf(':');
  +        final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
  +
  +        if (prefix != EMPTYSTRING || isElement) {
  +            uri = lookupNamespace(prefix);
  +            if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
  +                BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
  +                                          qname.substring(0, col));
  +            }
  +        }
  +        return uri;
  +    }
  +
  +    /**
  +     * Use a namespace prefix to lookup a namespace URI
  +     */
  +    private String lookupNamespace(String prefix) {
  +        final Stack stack = (Stack)_namespaces.get(prefix);
  +        return stack != null && !stack.isEmpty() ? (String)stack.peek() : null;
  +    }
  +
  +    
  +    private void closeCDATA() throws SAXException {
  +        // Output closing bracket - "]]>"
  +        _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
  +        _cdataTagOpen = false;
  +    }
  +
  +    /**
  +     * Put an attribute and its value in the start tag of an element.
  +     * Signal an exception if this is attempted done outside a start tag.
  +     */
  +    public void attribute(String name, final String value)
  +        throws TransletException 
  +    {
  +	final String patchedName = patchQName(name);
  +        final String localName = getLocalName(patchedName);
  +        final String uri = getNamespaceURI(patchedName, false);
  +        final int index = (localName == null) ?
  +                _attributes.getIndex(name) :    /* don't use patchedName */
  +                _attributes.getIndex(uri, localName);
  +        if (!_startTagOpen) {
  +            BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,
  +                patchedName);
  +        }
  +
  +	// Output as namespace declaration
  +        if (name.startsWith(XMLNS_PREFIX)) {
  +            namespace(name.length() > 6 ? name.substring(6) : EMPTYSTRING,
  +                value);
  +        }
  +        else {
  +            if (index >= 0) {       // Duplicate attribute?
  +                _attributes.setAttribute(index, uri, localName,
  +                    patchedName, "CDATA", value);
  +            }
  +            else {
  +                _attributes.addAttribute(uri, localName, patchedName,
  +                    "CDATA", value);
  +            }
  +        }
  +    }
  +
  +    public void characters(char[] ch, int off, int len)
  +        throws TransletException 
  +    {
  +	try {
  +            // Close any open start tag
  +            if (_startTagOpen) closeStartTag();
  +
  +            // 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. Other
  +            // special characters/sequences are _NOT_ escaped within CDATA.
  +            Integer I = (Integer)_cdataStack.peek();
  +            if ((I.intValue() == _depth) && (!_cdataTagOpen)) {
  +                startCDATA(ch, off, len);
  +            }
  +            else {
  +                _saxHandler.characters(ch, off, len);
  +            }
  +	}
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +    public void endElement(String elementName) throws TransletException {
  +        try {
  +            // Close any open element
  +            if (_startTagOpen) closeStartTag();
  +            if (_cdataTagOpen) closeCDATA();
  +
  +            final String qname = (String) _qnameStack.pop();
  +            _saxHandler.endElement(getNamespaceURI(qname, true),
  +                getLocalName(qname), qname);
  +
  +            popNamespaces();
  +            if (((Integer)_cdataStack.peek()).intValue() == _depth){
  +                _cdataStack.pop();
  +	    }
  +            _depth--;
  +
  +    	} catch (SAXException e) {
  +            throw new TransletException(e);
  +    	}
  +    }
  +
  +    /**
  +     * The <xsl:output method="xml"/> instruction can specify that certain
  +     * XML elements should be output as CDATA sections. This methods allows
  +     * the translet to insert these elements into a hashtable of strings.
  +     * Every output element is looked up in this hashtable before it is
  +     * output.
  +     */
  +    public void setCdataElements(Hashtable elements) {
  +        _cdata = elements;
  +    }
  +
  +    /**
  +     * Set the XML output document version - should be 1.0
  +     */
  +    public void setVersion(String version) {
  +        if (_saxHandler instanceof DefaultSAXOutputHandler) {
  +            ((DefaultSAXOutputHandler)_saxHandler).setVersion(version);
  +        }
  +    }
  +
  +    /**
  +     * Start an element in the output document. This might be an XML
  +     * element (<elem>data</elem> type) or a CDATA section.
  +     */
  +    public void startElement(String elementName) throws TransletException {
  +	try {
  +            // Close any open start tag
  +            if (_startTagOpen) closeStartTag();
  +            if (_cdataTagOpen) closeCDATA();
  +
  +            // Handle document type declaration (for first element only)
  +            if (_lexHandler != null) {
  +                if (_doctypeSystem != null) {
  +                    _lexHandler.startDTD(elementName,
  +                         _doctypePublic,_doctypeSystem);
  +		}
  +                _lexHandler = null;
  +            }
  +
  +            _depth++;
  +            _elementName = elementName;
  +            _attributes.clear();
  +            _startTagOpen = true;
  +            _qnameStack.push(elementName);
  +
  +            if ((_cdata != null) && (_cdata.get(elementName) != null)) {
  +                _cdataStack.push(new Integer(_depth));
  +	    }
  +	}
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +    /**
  +     * Initialize namespace stacks
  +     */
  +    private void initNamespaces() {
  +        _namespaces = new Hashtable();
  +        _nodeStack = new Stack();
  +        _prefixStack = new Stack();
  +
  +        // Define the default namespace (initially maps to "" uri)
  +        Stack stack;
  +        _namespaces.put(EMPTYSTRING, stack = new Stack());
  +        stack.push(EMPTYSTRING);
  +        _prefixStack.push(EMPTYSTRING);
  +
  +        _namespaces.put(XML_PREFIX, stack = new Stack());
  +        stack.push("http://www.w3.org/XML/1998/namespace");
  +        _prefixStack.push(XML_PREFIX);
  +
  +        _nodeStack.push(new Integer(-1));
  +        _depth = 0;
  +    }
  +
  +    /**
  +     * Pop all namespace definitions that were delcared by the current element
  +     */
  +    private void popNamespaces() throws TransletException {
  +        try {
  +            while (true) {
  +                if (_nodeStack.isEmpty()) return;
  +                Integer i = (Integer)(_nodeStack.peek());
  +                if (i.intValue() != _depth) return;
  +                _nodeStack.pop();
  +                popNamespace((String)_prefixStack.pop());
  +            }
  +        }
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
  +    }
  +
  +
  +    /**
  +     * Undeclare the namespace that is currently pointed to by a given prefix
  +     */
  +    private void popNamespace(String prefix) throws SAXException {
  +        // Prefixes "xml" and "xmlns" cannot be redefined
  +        if (prefix.equals(XML_PREFIX)) return;
  +
  +        Stack stack;
  +        if ((stack = (Stack)_namespaces.get(prefix)) != null) {
  +            stack.pop();
  +            _saxHandler.endPrefixMapping(prefix);
  +        }
  +    }
  +
  +
  +
  +
  +    /**
  +     * Utility method - pass a whole charactes as CDATA to SAX handler
  +     */
  +    private void startCDATA(char[] ch, int off, int len) throws SAXException {
  +        final int limit = off + len;
  +        int offset = off;
  +
  +        // Output start bracket - "<![CDATA["
  +        _saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
  +
  +        // Detect any occurence of "]]>" in the character array
  +        for (int i = offset; i < limit-2; i++) {
  +            if (ch[i] == ']' && ch[i+1] == ']' && ch[i+2] == '>') {
  +                _saxHandler.characters(ch, offset, i - offset);
  +                _saxHandler.characters(CNTCDATA, 0, CNTCDATA.length);
  +                offset = i+3;
  +                i=i+2; // Skip next chars ']' and '>'.
  +            }
  +        }
  +
  +        // Output the remaining characters
  +        if (offset < limit) _saxHandler.characters(ch, offset, limit - offset);
  +
  +        _cdataTagOpen = true;
  +    }
  +
   
   }
   
  
  
  

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