You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mi...@apache.org on 2003/10/21 21:27:37 UTC
cvs commit: xml-xalan/java/src/org/apache/xml/serializer ToXMLSAXHandler.java ToSAXHandler.java
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 - "<![CDATA["
- m_saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
- m_cdataTagOpen = true;
-
- }
-
- /**
- * 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["
- m_saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
-
- // Detect any occurence of "]]>" 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