2013-12-10 81 views
1

我有一個代碼,它使用JAXB和SAX將xml源解組到Java對象。後來我讀了this文檔,並知道如果我不提供SAX解析器,JAXB提供者將選擇一個默認解析器。默認解析器的含義是什麼?如果我不提供SAX 2.0解析器,它會使用DOM或其​​他技術解析文檔嗎?或者它會使用小於2.0版本的SAX解析器。支持SAX 2.0 compilant解析器

我們正在使用javax.xml.bind jaxb-api。我怎麼知道它使用了哪個SAX解析器。如果我必須確定使用JAXB的SAX2.0編譯器解析器,那麼可以使用哪些不同的解析器。這是什麼混亂?我完全搞砸了。至少我想閱讀一個很好的文檔,解釋有關解析技術,使用何種解析器以及不同類型的解析器和不同種類的JAXB提供程序等。

直到現在我只知道JAXB是一個規範。由Oracle分發的標準Java給出了規範的默認實現。除此之外還有Metro,Eclipselink MOXy,apache camel的JAXB實現等其他實現。剛纔我才知道,如果我理解正確,解析技術中會使用不同的解析器版本。

回答

0

備註:我是EclipseLink JAXB (MOXy)的領導者和JAXB (JSR-222)專家組的成員。

後來我讀了這篇文檔,發現如果我沒有提供一個 SAX解析器,JAXB提供者會選擇一個默認的解析器。 默認解析器是什麼意思?

當你問一個JAXB (JSR-222)實施解組類似的InputStream JAXB的實現可以自由地解析XML作爲它認爲合適(即SAX,StAX的,或一些專有解析器)。

如果要強制JAXB實現使用specfic SAX解析器那麼你可以做下列之一:

選項#1 - 的UnmarshallerHandler

import javax.xml.bind.*; 
import javax.xml.parsers.*; 
import org.xml.sax.XMLReader; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Foo.class); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler(); 

     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     spf.setNamespaceAware(true); 
     SAXParser sp = spf.newSAXParser(); 
     XMLReader xr = sp.getXMLReader(); 
     xr.setContentHandler(unmarshallerHandler); 
     xr.parse("input.xml"); 

     Foo foo = (Foo) unmarshallerHandler.getResult(); 
    } 

} 

選項#2 - SAXSource

您可以在XMLReader上創建SAXSource的實例,並從中取消JAXB解組。 JAXB將使用XMLReader傳入。

import javax.xml.bind.*; 
import javax.xml.parsers.*; 
import javax.xml.transform.sax.SAXSource; 
import org.xml.sax.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Foo.class); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 

     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     spf.setNamespaceAware(true); 
     SAXParser sp = spf.newSAXParser(); 
     XMLReader xr = sp.getXMLReader(); 

     InputSource xml = new InputSource("input.xml"); 

     SAXSource saxSource = new SAXSource(xr, xml); 
     Foo foo = (Foo) unmarshaller.unmarshal(saxSource); 
    } 

} 

到目前爲止我只知道,JAXB是一種規範。由Oracle分發的標準java 提供了 規範的默認實現。除此之外還有其他的實現,如Metro, Eclipselink MOXy,apache camel的JAXB實現。剛纔我發現 知道如果我理解正確,解析 技術時會使用不同的解析器版本。

最終,知道JAXB實現使用哪個底層解析器並不重要(它甚至可以在不同版本之間進行更改)。JAXB實現需要通過TCK,並將繼續以一致的方式工作。如果您希望它使用特定的SAX解析器,請使用上述方法之一。如果你想讓它使用StAX傳遞一個XMLStreamReader的實例來取消編組,並且如果你想讓它使用DOM傳遞一個Document的實例來取消編組。

+0

現在我正在使用選項#2。本部分「使用指定的驗證SAX2.0解析器的客戶端從javax.xml.transform.sax.SAXSource解組」,位於文檔http://docs.oracle.com/javaee/5/api/javax/xml/bind/ Unmarshaller.html讓我困惑。我不明白這是什麼。 –