2012-01-17 30 views
4

通過XSLT流式傳輸XML的許多示例,然後將JAXB轉換爲Java對象。他們往往是這樣的:通過轉換將數據流轉換爲JAXB Unmarshaller,併爲根元素聲明類類型

Transformer responseTransformer = TransformerFactory.newInstance().newTransformer(new StreamSource(getClass().getResourceAsStream("ResponseTransformation.xsl"))); 
Unmarshaller jaxbUnmarshaller = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName()).createUnmarshaller(); 

JAXBResult jaxbResult = new JAXBResult(jaxbUnmarshaller); 
responseTransformer.transform(new StreamSource(new StringReader(responseXml)), jaxbResult); 
res = jaxbResult.getResult(); 

也有聲明的類型像這樣通過JAXB解組的例子(從Unmarshaller的javadoc中):

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); 
Unmarshaller u = jc.createUnmarshaller(); 

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(new File("nosferatu.xml")); 
Element fooSubtree = ...; // traverse DOM till reach xml element foo, constrained by a 
          // local element declaration in schema. 

// FooType is the JAXB mapping of the type of local element declaration foo. 
JAXBElement<FooType> foo = u.unmarshal(fooSubtree, FooType.class); 

注意我們是如何指定FooType.class根請撥打u.unmarshal(fooSubtree, FooType.class)中的元素。尼斯。

問題是:有沒有一種方法可以像上面的例子一樣將處理流處理方式與指定聲明類型的方法結合起來?

我喜歡實現它的方式,但它需要訪問JAXB實現類。當然可以通過公共的JAXB接口來完成它,對嗎?

謝謝!

回答

1

您可以通過創建XMLFilter來訪問unmarshaller.unmarshal(source,type)方法。此代碼將允許您運行變換和反編排爲未綁定到根元素在XSD的對象:

import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLFilter; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBElement; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.util.JAXBResult; 
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.sax.SAXSource; 
import javax.xml.transform.sax.SAXTransformerFactory; 
import javax.xml.transform.stream.StreamSource; 
import static org.apache.commons.io.IOUtils.closeQuietly; 
... 
InputStream transformIn = null; 
InputStream sourceIn = null; 

try { 
    // get the transform and source streams. 
    transformIn = ...; 
    sourceIn = ...; 

    // create the filtered source 
    SAXTransformerFactory factory = (SAXTransformerFactory)TransformerFactory.newInstance(); 
    XMLFilter filter = factory.newXMLFilter(new StreamSource(transformIn)); 
    Source source = new SAXSource(filter, new InputSource(new InputStreamReader(sourceIn, "UTF-8"))); 

    // unmarshal the object. 
    Unmarshaller jaxbUnmarshaller = 
    JAXBContext.newInstance(ObjectFactory.class.getPackage().getName()).createUnmarshaller(); 
    JAXBElement<FooType> foo = jaxbUnmarshaller.unmarshal(source, FooType.class); 
} 
finally { 
    closeQuietly(transformIn); 
    closeQuietly(sourceIn); 
} 

警告:僅僅因爲你使用的是流API並不意味着實現是流式傳輸。在轉換文檔之前,大多數XSLT處理器將構建輸入的DOM樣式表示。如果您試圖避免在解組之前構建文檔,則此代碼可能不會這樣做。有關處理器的更多信息,請參閱this answer

相關問題