Why does the STAX parser think this is valid XML 1.0 but not 1.1?
java, stax, xml, xml-parsing
Solution
Hi This is a case of broken stax implementation in the Sun/Oracle JDK, IBM JDK works fine, or you can even just use the latest Xerces jars and you will be fine.
You can download xerces jars from: http://xerces.apache.org/mirrors.cgi#binary
dims@dims-laptop-520:~/test$ /usr/lib/jvm/java-6-sun/bin/java -cp . StaxSucks
Starting XML1.0
Stack is empty:true
Starting XML1.1
Exception in thread "main" java.lang.NullPointerException
at com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl.scanStartElement(XML11NSDocumentScannerImpl.java:351)
at com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl$NS11ContentDriver.scanRootElementHook(XML11NSDocumentScannerImpl.java:889)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3104)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:922)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl.next(XML11NSDocumentScannerImpl.java:852)
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:554)
at StaxSucks.parse(StaxSucks.java:26)
at StaxSucks.main(StaxSucks.java:54)
dims@dims-laptop-520:~/test$ java -cp .:xercesImpl.jar:xml-apis.jar StaxSucks
Starting XML1.0
Stack is empty:true
Starting XML1.1
Stack is empty:true
Problem
In the following code example, I use the STaX parser to parse a piece of XML. If I run the xml10 through it, it works as expected. The xml11 string (which is the same, except for the xml version) - it throws a NullPointerException. I'm running this on a Mac using JDK 1.6. ``` import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringReader; import java.util.Stack; /** */ public class StaxSucks { static String xml10 ="<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"+ "<anElement/>"; static String xml11 ="<?xml version=\"1.1\" encoding=\"utf-8\" ?>\n"+ "<anElement/>"; static void parse(InputStream is) throws Exception{ final XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); final XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(is); Stack<QName> XMLDEPTH = new Stack<QName>(); int eventType = xmlStreamReader.next(); while(eventType != XMLStreamConstants.END_DOCUMENT){ if(XMLStreamConstants.START_ELEMENT == eventType){ QName eventName = xmlStreamReader.getName(); XMLDEPTH.push(eventName); }else if(XMLStreamConstants.END_ELEMENT == eventType){ //ends should always match the starts. QName eventName = xmlStreamReader.getName(); if(XMLDEPTH.peek().equals(eventName)){ XMLDEPTH.pop(); }else{ System.out.println("Hit an end with a non-matching beginning:"+eventName); } } else{ System.out.println("Hit event type:"+eventType); } eventType = xmlStreamReader.next(); } System.out.println("Stack is empty:"+XMLDEPTH.empty()); } public static void main(String[] args) throws Exception{ System.out.println("Starting XML1.0"); InputStream is = new ByteArrayInputStream(xml10.getBytes("utf8")); parse(is); System.out.println("Starting XML1.1"); is = new ByteArrayInputStream(xml11.getBytes("utf8")); parse(is); } } ``` Stack Trace: ``` Exception in thread "main" java.lang.NullPointerException at com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl.scanStartElement(XML11NSDocumentScannerImpl.java:351) at com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl$NS11ContentDriver.scanRootElementHook(XML11NSDocumentScannerImpl.java:889) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3104) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:922) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648) at com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl.next(XML11NSDocumentScannerImpl.java:852) at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:554) at StaxSucks.parse(StaxSucks.java:46) at StaxSucks.main(StaxSucks.java:74) ```