为什么 STAX 解析器认为这是有效的 XML 1.0 而不是 1.1?
在下面的代码示例中,我使用 STaX 解析器来解析一段 XML.如果我通过它运行 xml10,它会按预期工作.xml11 字符串(相同,除了 xml 版本) - 它抛出 NullPointerException.我在使用 JDK 1.6 的 Mac 上运行它.
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" ?>
"+
"<anElement/>";
static String xml11 ="<?xml version="1.1" encoding="utf-8" ?>
"+
"<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);
}
}
堆栈跟踪:
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)
推荐答案
您好 这是 Sun/Oracle JDK 中 stax 实现损坏的案例,IBM JDK 工作正常,或者您甚至可以只使用最新的 Xerces jars会没事的.
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.
您可以从以下位置下载 xerces jar:http://xerces.apache.org/mirrors.cgi#binary
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
相关文章