Hi Xalan experts,
I've recently handled a customer issue about Text Nodes of value 'null' inside
a DOM, causing an exception during XALAN XSLT transformation. The repro case is
quite simple. Consider the following small Java sample [1] which creates a DOM
from a very basic XML, inserts a text node with value null into the DOM and
then runs an identity transformation on it. Without inserting the null Text
node, it would run without issues. However, the
com.sun.org.apache.xml.internal.serializer.ToUnknownStream class stumbles over
the null value and the transformation throws an NPE [2]. I believe this could
be easily fixed by adding a null check in the serializer and handling null like
"". However, would you agree that it is a real issue worth fixing or should one
rather stress the point that Text Nodes of null are illegal? (Is that true,
anyway? Didn't find any specification about that...) Please let me know your
opinion - and if you agree I would work on a fix.
Thanks in advance for comments
Christoph
[1] Sample code:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
public class TestTransformWithNullText {
public static void main(String[] args) throws
ParserConfigurationException, SAXException, IOException, TransformerException {
// create a small DOM
DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new
ByteArrayInputStream("<?xml version=\"1.0\"?><DOCROOT/>".getBytes()));
// insert a bad element
Element e = doc.createElement("ERROR");
e.appendChild(doc.createTextNode(null));
doc.getDocumentElement().appendChild(e);
// transform
ByteArrayOutputStream bos = new
ByteArrayOutputStream();
TransformerFactory.newInstance().newTransformer().transform(
new
DOMSource(doc.getDocumentElement()), new StreamResult(bos));
System.out.println(bos);
}
}
[2] Exception encountered:
Exception in thread "main" javax.xml.transform.TransformerException:
java.lang.NullPointerException
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform([email protected]/TransformerImpl.java:789)
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform([email protected]/TransformerImpl.java:376)
at
com.sap.cl.xml.test.transform.TestTransformWithNullText.main(TestTransformWithNullText.java:33)
Caused by: java.lang.NullPointerException
at
com.sun.org.apache.xml.internal.serializer.ToUnknownStream.characters([email protected]/ToUnknownStream.java:342)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:244)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:230)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:230)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:94)
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity([email protected]/TransformerImpl.java:718)
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform([email protected]/TransformerImpl.java:780)
... 2 more
---------
java.lang.NullPointerException
at
com.sun.org.apache.xml.internal.serializer.ToUnknownStream.characters([email protected]/ToUnknownStream.java:342)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:244)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:230)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:230)
at
com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse([email protected]/DOM2TO.java:94)
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity([email protected]/TransformerImpl.java:718)
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform([email protected]/TransformerImpl.java:780)
at
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform([email protected]/TransformerImpl.java:376)
at
com.sap.cl.xml.test.transform.TestTransformWithNullText.main(TestTransformWithNullText.java:33)