2012-05-23 9 views
5

W poniższym przykładzie kodu używam parsera STaX do parsowania fragmentu XML. Jeśli uruchomię Xml10 przez niego, działa zgodnie z oczekiwaniami. Łańcuch xml11 (który jest taki sam, z wyjątkiem wersji xml) - powoduje zgłoszenie wyjątku NullPointerException. Używam tego na Macu używając JDK 1.6.Dlaczego parser STAX uważa, że ​​jest to poprawne XML 1.0, ale nie 1.1?

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); 
    } 
} 

stosu Ślad:

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) 
+0

można zakładać ślad stosu? – SantoshK

+0

Dodano ślad stosu. – Kylar

+1

Wygląda jak prawdziwy błąd ... Zauważam, jeśli zmienisz ciąg XML1.1 na: static String xml11 = " \ N" + ""; to działa dobrze. –

Odpowiedz

3

Cześć Jest to przypadek połamanych realizacji Stax w Sun/Oracle JDK IBM JDK działa dobrze, czy nawet po prostu korzystać z najnowszych XERCES słoiki i ci będzie dobrze.

Można pobrać XERCES słoiki z: http://xerces.apache.org/mirrors.cgi#binary

[email protected]:~/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) 
[email protected]:~/test$ java -cp .:xercesImpl.jar:xml-apis.jar StaxSucks 
Starting XML1.0 
Stack is empty:true 
Starting XML1.1 
Stack is empty:true 
+0

Zaakceptowany, ale nadal frustrujący :(Nie mam kontroli nad uruchomieniem aplikacji, a integracja nowych słoików jest ogromnym problemem. Jednak, dzięki weryfikacji, czy rzeczywiście jest to błąd w JDK. – Kylar

+0

to jest błąd czy jest tam wpis błędu? – eis

+0

ah, [tutaj] (https://bugs.openjdk.java.net/browse/JDK-8029437) to jest. – eis

Powiązane problemy