5

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)
4

1 回答 1

3

嗨,这是 Sun/Oracle JDK 中 stax 实现损坏的案例,IBM JDK 工作正常,或者您甚至可以只使用最新的 Xerces jar 就可以了。

您可以从以下位置下载 xerces jar: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
于 2012-05-23T23:41:24.410 回答