2012-10-05 25 views
6

के साथ जेएक्सबी unmarshalling मैं JAXB का उपयोग कर एक विरासत प्रणाली से एक XML दस्तावेज़ unmarshall करने की कोशिश कर रहा हूँ।जावा जेनेरिक

<response> 
    <id>000000</id> 
    <results> 
     <result> 
<!-- Request specific xml content --> 
      <year>2003</year> 
      <title>Lorem Ipsum</title> 
      <items> 
       <item>I1</item> 
       <item>I2</item> 
      </items> 
     </result> 
     <result> 
      <year>2007</year> 
      <title>Dolor sit amet</title> 
      <items> 
       <item>K1</item> 
       <item>K2</item> 
      </items> 
     </result> 
    </results> 
</response> 

हिस्सा <result> टैग द्वारा निर्दिष्ट मेरे अनुरोध के आधार पर बदल जाएगा अंदर टैग: मैं एक xml संरचना इस प्रकार की है। के बाद से सामग्री बदल सकती है मैं परिणाम मदों के लिए जेनरिक का उपयोग करने का फैसला किया है और मैं निम्नलिखित के रूप में एनोटेशन के साथ मेरी जावा सेम तैयार किया है:

JAXBContext context = JAXBContext.newInstance(XResponse.class, X1Result.class); 
Unmarshaller um = context.createUnmarshaller(); 
XResponse<X1Result> response = (XResponse<X1Result>) um.unmarshal(xmlContent); 

List<X1Result> results = unmarshal.getResults(); 
for (X1Result object : results) { 
    System.out.println(object.getClass()); 
} 

:

// imports here 
@XmlRootElement(name="response") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class XResponse<T>{ 
    private String id; 

    @XmlElementWrapper(name="results") 
    @XmlElement(name="result") 
    private List<T> results; 

// setters and getters 
} 

... 

@XmlRootElement(name="result") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class X1Result{ 
    private String year; 
    private String title; 
    @XmlElementWrapper(name="items") 
    @XmlElement(name="item") 
    private List<String> items; 

// setters and getters 
} 
... 

मैं नीचे दिए गए कोड के माध्यम से XML दस्तावेज़ unmarshalling की कोशिश की मुझे unmarshalling के दौरान एक समस्या है कि यह सूची आइटम X1Result कक्षा में नहीं डाल सकता है। इसके बजाय यह org.apache.xerces.dom.ElementNSImpl का उपयोग करता है।

जेएक्सबी Unmarshaller X1Result कक्षा का उपयोग करने के लिए मुझे क्या करना चाहिए?

अग्रिम धन्यवाद

उत्तर

2

में मुझे लगता है कि आप जेनरिक के बजाय विरासत का उपयोग करना चाहिए। इस तरह एक XML को देखते हुए:

<?xml version="1.0" encoding="UTF-8"?> 
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <id>000000</id> 
    <results> 
     <result xsi:type="X1Result"> 
      <year>2003</year> 
      <title>Lorem Ipsum</title> 
      <items> 
       <item>I1</item> 
       <item>I2</item> 
      </items> 
     </result> 
     <result xsi:type="X1Result"> 
      <year>2007</year> 
      <title>Dolor sit amet</title> 
      <items> 
       <item>K1</item> 
       <item>K2</item> 
      </items> 
     </result> 
    </results> 
</response> 

आप गतिशील रूप से अपने <result> प्रविष्टियों बाध्य कर सकते हैं। आप एक शीर्ष स्तर प्रकार है:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "XResult") 
@XmlSeeAlso({ 
    X1Result.class 
})public abstract class XResult { 

} 

और आप को लागू करने श्रेणियां होती हैं:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "X1Result") 
public class X1Result extends XResult { 
    @XmlElement(name = "year") 
    private String year; 

    @XmlElement(name = "title") 
    private String title; 

    @XmlElementWrapper(name = "items") 
    @XmlElement(name = "item") 
    private List<String> items; 
    ... 
} 

उपयोग आपकी XResponse वर्ग में शीर्ष स्तर के प्रकार:

@XmlRootElement(name = "response") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class XResponse { 
    @XmlElement(name = "id") 
    private String id; 

    @XmlElementWrapper(name = "results") 
    @XmlElement(name = "result") 
    private List<XResult> results; 
    ... 
} 

और तुम unmarshall कर सकते हैं शीर्ष-स्तरीय प्रकार का उपयोग करके:

context = JAXBContext.newInstance(XResponse.class, XResult.class); 
Unmarshaller unmarshaller = context.createUnmarshaller(); 
XResponse response = (XResponse) unmarshaller.unmarshal(new File("testfile.xml")); 

List<XResult> results = response.getResults(); 
for (XResult object : results) { 
    System.out.println(object.getClass()); 
} 
+0

उपरोक्त कोड 'X1Result' के बजाय' XResult' को ializes और इसलिए यह त्रुटि देता है क्योंकि यह एक सार वर्ग है। एक्सएमएल की सामग्री के अलावा एक विरासत प्रणाली से आ रहा है और कोई 'xsi: type' जानकारी उपलब्ध नहीं है। (हालांकि मैं इसे प्रोग्रामेटिक रूप से जोड़ सकता हूं) – Alper

+0

यदि कोड 'xsi: type' है तो कोड' X1Result' को चालू करेगा। कम से कम, यह मेरे लिए यह करता है। सौभाग्य। – davidfmatheson

+0

यह एक्सएमएल में मौजूद 'xsi: type' के बिना मेरे लिए ठीक काम करता है। मैं जावा 1.7.0_15 का उपयोग कर रहा हूँ। –

संबंधित मुद्दे