2011-10-21 16 views
8

का उपयोग कर जेनरेट एक्सएमएल में डुप्लिकेट फ़ील्ड यह मेरा परिदृश्य है।जेएक्सबी

public class Tuple<T> extends ArrayList<T> { 
    //... 
    public Tuple(T ...members) { 
    this(Arrays.asList(members)); 
    } 

    @XmlElementWrapper(name = "tuple") 
    @XmlElement(name = "value") 
    public List<T> getList() { 
    return this; 
    } 
} 

और एक बच्चे के वर्ग:

public class StringTuple extends Tuple<String> { 
    public StringTuple(String ...members) { 
    super(members); 
    } 

    //explanation of why overriding this method soon ... 
    @XmlElementWrapper(name = "tuple") 
    @XmlElement(name = "value") 
    @Override 
    public List<String> getList() { 
    return this; 
    } 
} 

इन कक्षाओं यहां संदर्भित कर रहे हैं:

:

@XmlRootElement(namespace = "iv4e.xml.jaxb.model") 
public class Relation { 
    private Tuple<StringTuple> relationVars; 
    //... 
    @XmlElementWrapper(name = "allRelationVars") 
    @XmlElement(name = "relationVarsList") 
    public Tuple<StringTuple> getRelationVars() { 
    return relationVars; 
    } 
} 

फिर एक रिलेशन वस्तु की तरह कुछ के साथ बनाई गई है मैं एक सामान्य वर्ग है

Relation rel = new Relation(); 
rel.setRelationVars(new Tuple<StringTuple>(
    new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2"))); 

marshalling के बाद इस वस्तु, एक्सएमएल उत्पादन निम्नलिखित है:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:relation xmlns:ns2="iv4e.xml.jaxb.model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=""> 

    <allRelationVars> 
    <relationVarsList> 
     <tuple> 
      <value xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">RelationshipVar1</value> 
     </tuple> 
     <tuple> 
      <value>RelationshipVar1</value> 
     </tuple> 
    </relationVarsList> 
    <relationVarsList> 
     <tuple> 
      <value xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">RelationshipVar2</value> 
     </tuple> 
     <tuple> 
      <value>RelationshipVar2</value> 
     </tuple> 
    </relationVarsList> 
    </allRelationVars> 

</ns2:relation> 

तो value तत्वों को दोहराया गया है !.

अब, कारण वर्ग StringTuple ओवरराइड करता है List<T> getList()List<String> getList() साथ सूची (xml दस्तावेज़ में value तत्व) के हर सदस्य में कष्टप्रद उत्पन्न xmlns:xs विशेषताओं से परहेज कर रहा है। लेकिन फिर सूची के प्रत्येक सदस्य को आउटपुट में दो बार दिखाया गया है। जाहिर है, ऐसा इसलिए है क्योंकि ओवरराइड पेरेंट विधि और बाल विधि दोनों को @XmlElement के साथ एनोटेट किया गया है। तो मेरा मुख्य प्रश्न यह है: जैक्सब में @XmlElement के साथ एनोटेटेड विधियों को अनदेखा करने का एक तरीका है? (इस बात पर विचार करते हुए कि @XmlElement के साथ ओवरराइडिंग विधि भी एनोटेटेड है)

मुझे एक पुरानी पोस्ट रिपोर्टिंग एक जैसी समस्या मिली: http://old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html, लेकिन मुझे अभी तक कोई समाधान नहीं मिला है। यह भी ध्यान दें कि @XmlTransient पेरेंट क्लास (Tuple<T>) पर getList विधि पर एनोटेशन जोड़ने से इस समस्या को हल किया जा सकता है लेकिन अन्य उत्पन्न होंगे, क्योंकि अभिभावक वर्ग सार नहीं है और अन्य संदर्भों में अकेले उपयोग किया जाता है।

एक तरफ माध्यमिक प्रश्न: क्या इसके बजाय रूट नोड पर xmlns:xs विशेषता घोषित करना संभव है -नहीं- हर नोड में जहां दिखाना आवश्यक है? मुझे पता है कि यह NamespacePrefixMapper वर्ग के साथ किया जा सकता है, लेकिन चूंकि यह एक गैर मानक, सूर्य आंतरिक वर्ग है, इसलिए मैं अधिक कार्यान्वयन स्वतंत्र दृष्टिकोण का उपयोग करना पसंद करता हूं।

किसी भी प्रतिक्रिया के लिए अग्रिम धन्यवाद!

+1

इससे पहले कि मैं इस मुद्दे में बहुत दूर हूं, क्या आपके डोमेन ऑब्जेक्ट्स को 'ऐरेलिस्ट' का विस्तार करने की आवश्यकता है? 'Trayle'' ArrayList' प्रकार की संपत्ति रखने के बजाय 'ArrayList' क्यों बढ़ाता है? –

+0

हाय ब्लेज़ !, मैंने ऐरेलिस्ट से विरासत को चुना क्योंकि मेरी ट्यूपल ऑब्जेक्ट वास्तव में एक ऐरेलिस्ट है। हालांकि, मैं इसके साथ एक ऐरेलिस्टिस्ट के साथ रह सकता था, हालांकि मुझे कुछ प्रतिनिधिमंडल विधियों को लागू करना होगा। वैसे भी, यह मेरी समस्या का समाधान नहीं करेगा क्योंकि मेरे पास अभी भी एक ट्यूपल जेनेरिक क्लास होगा, और स्ट्रिंग टुपल टुपल का विस्तार करेगा। – Sergio

+0

मैंने एक दृष्टिकोण के साथ एक उत्तर जोड़ा है जिसका उपयोग 'xsi: type' घोषणा से छुटकारा पाने के लिए किया जा सकता है। –

उत्तर

3

आप माता-पिता पर संपत्ति @XmlTransient और @XmlElement बच्चे पर अंकन के निम्नलिखित दृष्टिकोण इस्तेमाल कर सकते हैं:

जनक

package forum7851052; 

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlTransient; 

@XmlRootElement 
public class Parent<T> { 

    private List<T> item = new ArrayList<T>(); 

    @XmlTransient 
    public List<T> getItem() { 
     return item; 
    } 

    public void setItem(List<T> item) { 
     this.item = item; 
    } 

} 

IntegerChild

package forum7851052; 

import java.util.List; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class IntegerChild extends Parent<Integer> { 

    @Override 
    @XmlElement 
    public List<Integer> getItem() { 
     return super.getItem(); 
    } 

    @Override 
    public void setItem(List<Integer> item) { 
     super.setItem(item); 
    } 

} 

StringC HILD

package forum7851052; 

import java.util.List; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class StringChild extends Parent<String> { 

    @Override 
    @XmlElement 
    public List<String> getItem() { 
     return super.getItem(); 
    } 

    @Override 
    public void setItem(List<String> item) { 
     super.setItem(item); 
    } 

} 

डेमो

package forum7851052; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Parent.class, IntegerChild.class, StringChild.class); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     IntegerChild integerChild = new IntegerChild(); 
     integerChild.getItem().add(1); 
     integerChild.getItem().add(2); 
     marshaller.marshal(integerChild, System.out); 

     StringChild stringChild = new StringChild(); 
     stringChild.getItem().add("A"); 
     stringChild.getItem().add("B"); 
     marshaller.marshal(stringChild, System.out); 
    } 

} 

आउटपुट

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<integerChild> 
    <item>1</item> 
    <item>2</item> 
</integerChild> 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<stringChild> 
    <item>A</item> 
    <item>B</item> 
</stringChild> 
+0

क्या होगा अगर माता-पिता को क्रमिकरण में भी उपयोग किया जाता है (माता-पिता का क्षेत्र क्षणिक बनाना एक विकल्प नहीं है)? यह बिल्कुल वैध मामला होना चाहिए, फिर भी जेएक्सबी @ ओवरराइड एनोटेशन में शामिल है। – stuchl4n3k

2

यह काफी पुराना हो सकता है, लेकिन इसके पहले परिणाम जबकि "JAXB क्षेत्रों नकल"

के लिए खोज

एक ही समस्या पर ठोकर खाई, यह मेरे लिए चाल है:

@XmlRootElement 
@XmlAccessorType(XmlAccessType.NONE) // <-- made the difference 
public abstract class ParentClass 
{ 
... 
} 


@XmlRootElement 
public class ChildClass extends ParentClass 
{ 
... 
} 
संबंधित मुद्दे