beckchr / staxon

JSON via StAX
107 stars 47 forks source link

JsonXMLStreamReader.getVersion() returns always null #11

Closed gub closed 12 years ago

gub commented 12 years ago

If I try to convert from JSON to DOM using staxon, I get a NullPointerException. For converting I use the standard Transformer and StAXSource contained in JRE 6. The code I am using is as follows:

static Document readJson(InputStream inStream) throws XMLStreamException, TransformerException {
    XMLStreamReader in = null;
    try {
        XMLInputFactory inFactory = new JsonXMLInputFactory();
        in = inFactory.createXMLStreamReader(inStream);
        Transformer trans = TransformerFactory.newInstance().newTransformer();
        DOMResult result = new DOMResult();
        trans.transform(new StAXSource(in), result);
        return (Document) result.getNode();
    } finally {
        if(in!=null) try { in.close(); } catch (XMLStreamException e) { e.printStackTrace(); }
    }        
}

The complete exception stack trace is: Exception in thread "main" javax.xml.transform.TransformerException: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:716) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:313) at json.StaxonBug.readJson(StaxonBug.java:43) at json.StaxonBug.main(StaxonBug.java:33) Caused by: java.lang.NullPointerException at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.setXmlVersion(CoreDocumentImpl.java:856) at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.setDocumentInfo(SAX2DOM.java:150) at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.startElement(SAX2DOM.java:160) at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.closeStartTag(ToXMLSAXHandler.java:204) at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.characters(ToXMLSAXHandler.java:524) at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.handleCharacters(StAXStream2SAX.java:264) at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.bridge(StAXStream2SAX.java:171) at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.parse(StAXStream2SAX.java:120) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:656) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707) ... 3 more

The reason for the NullPointerException is, that JsonXMLStreamReader.getVersion() returns null. It is set to null in readStartDocument() which is called only in JsonXMLStreamReader line 147.

Could you please add a possibility to set the version to something different.

beckchr commented 12 years ago

Thanks for reporting this. The Javadoc for XMLStreamReader.getVersion() says

Get the xml version declared on the xml declaration Returns null if none was declared

With JSON as source, there's clearly no version declared, so I'd like to leave things as they are. To fix the problem with Xalan, consider one of the following workarounds:

Wrap or subclass JSONXMLStreamReader

XMLStreamReader in = new StreamReaderDelegate(inFactory.createXMLStreamReader(inStream)) {
  @Override
  public String getVersion() {
    return "1.0";
  }
};
Transformer trans = TransformerFactory.newInstance().newTransformer();
DOMResult result = new DOMResult();
trans.transform(new StAXSource(in), result);
return (Document) result.getNode();

Use StAXON's DOMEventConsumer class (recommended)

XMLStreamReader in = inFactory.createXMLEventReader(inStream);
return DOMEventConsumer.consume(in);
gub commented 12 years ago

Thank you for the quick response!

Both of your workarounds work well for me. It even works if I just replace XMLStreamReader with XMLEventReader in my original code.