Return-Path: Delivered-To: apmail-xml-xalan-cvs-archive@www.apache.org Received: (qmail 58622 invoked from network); 21 Oct 2003 19:27:38 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 21 Oct 2003 19:27:38 -0000 Received: (qmail 83931 invoked by uid 500); 21 Oct 2003 19:27:27 -0000 Delivered-To: apmail-xml-xalan-cvs-archive@xml.apache.org Received: (qmail 83865 invoked by uid 500); 21 Oct 2003 19:27:27 -0000 Mailing-List: contact xalan-cvs-help@xml.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: Delivered-To: mailing list xalan-cvs@xml.apache.org Received: (qmail 83852 invoked from network); 21 Oct 2003 19:27:27 -0000 Received: from unknown (HELO minotaur.apache.org) (209.237.227.194) by daedalus.apache.org with SMTP; 21 Oct 2003 19:27:27 -0000 Received: (qmail 58608 invoked by uid 1663); 21 Oct 2003 19:27:37 -0000 Date: 21 Oct 2003 19:27:37 -0000 Message-ID: <20031021192737.58607.qmail@minotaur.apache.org> From: minchau@apache.org To: xml-xalan-cvs@apache.org Subject: cvs commit: xml-xalan/java/src/org/apache/xml/serializer ToXMLSAXHandler.java ToSAXHandler.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N minchau 2003/10/21 12:27:37 Modified: java/src/org/apache/xml/serializer ToXMLSAXHandler.java ToSAXHandler.java Log: PR: bugzilla 23812 Submitted by: Brian Minchau Reviewed by: Henry Zongaro Fixes incorrect handling of CDATA by a ToXMLSAXHandler. The CDATA was defined by calls to the LexicalHandler methods: startCDATA() endCDATA() Henry would rather have a new flushPending() method which does not flush a generated endCDATA() call, but I copied the contents of flushPending() to the top of ToXMLSAXHandler.character(char[] chars, int off, int len) anyways. I didn't want to put a new flushPending() method on a SerializationHandler interface. I'm not completely happy with either choice so I left it as-was - bjm Revision Changes Path 1.9 +80 -48 xml-xalan/java/src/org/apache/xml/serializer/ToXMLSAXHandler.java Index: ToXMLSAXHandler.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToXMLSAXHandler.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ToXMLSAXHandler.java 7 Jul 2003 06:23:51 -0000 1.8 +++ ToXMLSAXHandler.java 21 Oct 2003 19:27:37 -0000 1.9 @@ -252,14 +252,26 @@ } /** - * Closes the open cdata tag + * Closes ane open cdata tag, and + * unlike the this.endCDATA() method (from the LexicalHandler) interface, + * this "internal" method will send the endCDATA() call to the wrapped + * handler. + * */ public void closeCDATA() throws SAXException { // Output closing bracket - "]]>" - m_saxHandler.characters(ENDCDATA, 0, ENDCDATA.length); - m_cdataTagOpen = false; + if (m_lexHandler != null && m_cdataTagOpen) { + m_lexHandler.endCDATA(); + } + + + // There are no longer any calls made to + // m_lexHandler.startCDATA() without a balancing call to + // m_lexHandler.endCDATA() + // so we set m_cdataTagOpen to false to remember this. + m_cdataTagOpen = false; } /** @@ -435,8 +447,27 @@ */ public void endCDATA() throws SAXException { - if (m_lexHandler != null) - m_lexHandler.endCDATA(); + /* Normally we would do somthing with this but we ignore it. + * The neccessary call to m_lexHandler.endCDATA() will be made + * in flushPending(). + * + * This is so that if we get calls like these: + * this.startCDATA(); + * this.characters(chars1, off1, len1); + * this.endCDATA(); + * this.startCDATA(); + * this.characters(chars2, off2, len2); + * this.endCDATA(); + * + * that we will only make these calls to the wrapped handlers: + * + * m_lexHandler.startCDATA(); + * m_saxHandler.characters(chars1, off1, len1); + * m_saxHandler.characters(chars1, off2, len2); + * m_lexHandler.endCDATA(); + * + * We will merge adjacent CDATA blocks. + */ } /** @@ -515,18 +546,35 @@ public void characters(char[] ch, int off, int len) throws SAXException { - // System.out.println("SAXXMLOutput.characters ch = " + new String(ch, off, len)); - - flushPending(); + // We do the first two things in flushPending() but we don't + // close any open CDATA calls. + if (m_needToCallStartDocument) + { + startDocumentInternal(); + m_needToCallStartDocument = false; + } - if (m_elemContext.m_isCdataSection) + if (m_elemContext.m_startTagOpen) { - startCDATA(ch, off, len); + closeStartTag(); + m_elemContext.m_startTagOpen = false; } - else + + if (m_elemContext.m_isCdataSection && !m_cdataTagOpen + && m_lexHandler != null) { - m_saxHandler.characters(ch, off, len); + m_lexHandler.startCDATA(); + // We have made a call to m_lexHandler.startCDATA() with + // no balancing call to m_lexHandler.endCDATA() + // so we set m_cdataTagOpen true to remember this. + m_cdataTagOpen = true; } + + /* If there are any occurances of "]]>" in the character data + * let m_saxHandler worry about it, we've already warned them with + * the previous call of m_lexHandler.startCDATA(); + */ + m_saxHandler.characters(ch, off, len); // time to generate characters event if (m_tracer != null) @@ -598,47 +646,31 @@ public void startCDATA() throws SAXException { - - // Output start bracket - "" in the character array - for (int i = offset; i < limit - 2; i++) + /* m_cdataTagOpen can only be true here if we have ignored the + * previous call to this.endCDATA() and the previous call + * this.startCDATA() before that is still "open". In this way + * we merge adjacent CDATA. If anything else happened after the + * ignored call to this.endCDATA() and this call then a call to + * flushPending() would have been made which would have + * closed the CDATA and set m_cdataTagOpen to false. + */ + if (!m_cdataTagOpen ) { - if (ch[i] == ']' && ch[i + 1] == ']' && ch[i + 2] == '>') - { - m_saxHandler.characters(ch, offset, i - offset); - m_saxHandler.characters(CNTCDATA, 0, CNTCDATA.length); - offset = i + 3; - i += 2; // Skip next chars ']' and '>' - } - } + flushPending(); + if (m_lexHandler != null) { + m_lexHandler.startCDATA(); - // Output the remaining characters - if (offset < limit) - { - m_saxHandler.characters(ch, offset, limit - offset); - } - m_cdataTagOpen = true; + // We have made a call to m_lexHandler.startCDATA() with + // no balancing call to m_lexHandler.endCDATA() + // so we set m_cdataTagOpen true to remember this. + m_cdataTagOpen = true; + } + } } /** - * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes) - */ + * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes) + */ public void startElement( String namespaceURI, String localName, 1.8 +8 -4 xml-xalan/java/src/org/apache/xml/serializer/ToSAXHandler.java Index: ToSAXHandler.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToSAXHandler.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ToSAXHandler.java 6 Oct 2003 14:33:07 -0000 1.7 +++ ToSAXHandler.java 21 Oct 2003 19:27:37 -0000 1.8 @@ -357,7 +357,7 @@ } /** - * This method gets the nodes value as a String and uses that String as if + * This method gets the node's value as a String and uses that String as if * it were an input character notification. * @param node the Node to serialize * @throws org.xml.sax.SAXException @@ -371,9 +371,13 @@ m_state.setCurrentNode(node); } - // do what the stream serializers do - super.characters(node); - } + // Get the node's value as a String and use that String as if + // it were an input character notification. + String data = node.getNodeValue(); + if (data != null) { + this.characters(data); + } + } /** * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException) --------------------------------------------------------------------- To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org For additional commands, e-mail: xalan-cvs-help@xml.apache.org