问题
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)
回答1:
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
来源:https://stackoverflow.com/questions/10727288/why-does-the-stax-parser-think-this-is-valid-xml-1-0-but-not-1-1