2009-05-20 12 views
5

की मैं स्कीमाJAXB सूची च्वाइस

<complexType name="BookShelf"> 
    <sequence> 
     <element name="newBook" type="string" minOccurs="0" maxOccurs="unbounded"/> 
     <element name="oldBook" type="string" minOccurs="0" maxOccurs="unbounded"/> 
    </sequence> 
</complexType> 

XJC निम्नलिखित है दो सूचियों, newBook ​​के लिए एक और oldBook के लिए एक साथ पुस्ताक तख्ता वर्ग उत्पन्न करता है। अति उत्कृष्ट!

अब मैं पुस्तकों को किसी भी क्रम में दिखाना चाहता हूं। तो मैं करने के लिए मेरे स्कीमा पुनर्लेखन:

<complexType name="BookShelf"> 
    <sequence> 
     <choice minOccurs="0" maxOccurs="unbounded"> 
     <element name="newBook" type="string"/> 
     <element name="oldBook" type="string"/> 
     </choice> 
    </sequence> 
</complexType> 

लेकिन अब XJC प्रकार List<JAXBElement<String>> का केवल एक ही सूची newBookOrOldBook साथ पुस्ताक तख्ता उत्पन्न करता है।

मुझे उस ऑर्डर की परवाह नहीं है जिसमें किताबें दिखाई देती हैं और मैं XML लेखक को किसी भी क्रम में पुस्तकें निर्दिष्ट करने की अनुमति देना चाहता हूं, लेकिन मैं अभी भी प्रत्येक प्रकार की पुस्तकें जेनरेट बुकशेल्फ़ क्लास में सूची के रूप में चाहता हूं। क्या मैं इसे हासिल कर सकता हूं?

+0

स्पष्टीकरण:: में

<xs:complexType name="typeWithReferencesProperty"> <xs:choice maxOccurs="unbounded"> <xs:element name="a" type="someType"> <xs:annotation> <xs:appinfo> <simplify:as-element-property/> </xs:appinfo> </xs:annotation> </xs:element> <xs:element name="b" type="someType"/> </xs:choice> </xs:complexType> 

परिणाम आप उदाहरण एक के रूप में एक ही कक्षा चाहते हैं, लेकिन उदाहरण दो में स्कीमा का उपयोग कर? (और निश्चित रूप से, सूचियां अलग-अलग लंबाई के हो सकती हैं) – 13ren

+0

इसके अलावा, "सूची>" पर आपके वाक्यविन्यास के साथ कुछ हुआ - संभवतः आपने कोड इनलाइन से बचने के लिए '' छोड़ा था। – 13ren

उत्तर

0

शायद ऐसा कुछ हो सकता है?

<schema 
    elementFormDefault = "qualified" 
    xmlns    = "http://www.w3.org/2001/XMLSchema" 
    xmlns:xs   = "http://www.w3.org/2001/XMLSchema" 
    xmlns:tns   = "urn:cheeso.examples.2009.05.listofbooks" 
    targetNamespace = "urn:cheeso.examples.2009.05.listofbooks" 
    > 

    <element name="Shelf" nillable="true" type="tns:BookShelf" /> 

    <complexType name="BookShelf"> 
    <sequence> 
     <element minOccurs="0" maxOccurs="1" name="Store" type="tns:ArrayOfChoice1" /> 
    </sequence> 
    </complexType> 

    <complexType name="ArrayOfChoice1"> 
    <choice minOccurs="0" maxOccurs="unbounded"> 
     <element minOccurs="1" maxOccurs="1" name="newBook" nillable="true" type="tns:newBook" /> 
     <element minOccurs="1" maxOccurs="1" name="oldBook" nillable="true" type="tns:oldBook" /> 
    </choice> 
    </complexType> 

    <complexType name="Book"> 
    <attribute name="name" type="string" /> 
    </complexType> 

    <complexType name="newBook"> 
    <complexContent mixed="false"> 
     <extension base="tns:Book" /> 
    </complexContent> 
    </complexType> 

    <complexType name="oldBook"> 
    <complexContent mixed="false"> 
     <extension base="tns:Book" /> 
    </complexContent> 
    </complexType> 

</schema> 

बेशक आप

<schema 
    elementFormDefault = "qualified" 
    xmlns    = "http://www.w3.org/2001/XMLSchema" 
    xmlns:xs   = "http://www.w3.org/2001/XMLSchema" 
    xmlns:tns   = "urn:cheeso.examples.2009.05.listofbooks" 
    targetNamespace = "urn:cheeso.examples.2009.05.listofbooks" 
    > 

    <element name="Shelf" nillable="true" type="tns:BookShelf" /> 

    <complexType name="BookShelf"> 
    <sequence> 
     <element minOccurs="0" maxOccurs="1" name="Store" type="tns:ArrayOfChoice1" /> 
    </sequence> 
    </complexType> 

    <complexType name="ArrayOfChoice1"> 
    <choice minOccurs="0" maxOccurs="unbounded"> 
     <element minOccurs="1" maxOccurs="1" name="newBook" nillable="true" type="xs:string" /> 
     <element minOccurs="1" maxOccurs="1" name="oldBook" nillable="true" type="xs:string" /> 
    </choice> 
    </complexType> 

</schema> 
+0

आपके उत्तर के लिए धन्यवाद। क्षमा करें, लेकिन मैं अपने प्रश्न में अस्पष्ट था। पुरानेबुक और न्यूबुक दोनों में सामान्य फ़ील्ड के साथ-साथ अलग-अलग होंगे और मैं जावा कोड में कास्टिंग से बचना चाहता हूं। उपर्युक्त वर्णित स्कीमा में, जब पुराने पुस्तक और नए पुस्तक में स्ट्रिंग प्रकार होता है, तो JAXB JAXBElement की सूची जेनरेट करेगा और उदाहरण के बजाय किसी को कास्टिंग करने के लिए JAXBElement पर getName को आवश्यक प्रकार के तत्व को निर्धारित करने के लिए कॉल करना होगा। क्या यह स्थिति एक्सएमएल डिज़ाइन के लिए गलत हो सकती है? और मुझे पुरानेबुक और न्यूबुक गणना को अलग करना चाहिए? – olek

+0

आपको एक अतिसंवेदनशील समस्या हो सकती है, मुझे संदेह है। मुझे जेएक्सबी के बारे में बहुत कुछ पता नहीं है और एक्सएसडी से उत्पन्न ऑब्जेक्ट मॉडल को आकार देने की संभावना है। अकेले तत्व नाम से उसी प्रकार के डेटा को अलग करने के लिए, getName() को कॉल करने के लिए आपके प्रोग्राम की आवश्यकता होती है। यदि आप स्कीमा का आकार बदलते हैं, तो आप का उपयोग कर सकते हैं, इस मामले में आपको getName() को कॉल नहीं करना पड़ेगा। इसके बजाय आपके पास एक अलग ऑब्जेक्ट मॉडल होगा। या आप मेरे पहले उदाहरण स्कीमा के रूप में, नए पुस्तक और पुराने पुस्तक के लिए नए जटिल प्रकार निर्दिष्ट कर सकते हैं। यह आप पर निर्भर करता है। – Cheeso

0

लिए मुझे नहीं लगता कि इस JAXB में संभव है कुछ कस्टम जावा या XSLT लेखन के बिना, को आसान बनाने में कर सकता है।

जेएक्सबी ऑब्जेक्ट्स और एक्सएमएल के बीच मैपिंग में बहुत अच्छा नहीं है जिसमें आपकी संरचना जैसी अलग-अलग संरचना है। साथ ही, जावा में दो अलग-अलग सूचियों में परिवर्तित होने पर एक्सएमएल में नई किताबों के संबंध में पुरानी किताब का ऑर्डर खो जाएगा, और जेएक्सबी आम तौर पर जानकारी को संरक्षित करना चाहता है।

आपके प्रश्न का उत्तर नहीं है निम्नलिखित है, लेकिन शायद यह तुम क्या चाहते दिशा में एक कदम है:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="bookShelf" type="BookShelf"/> 
    <xs:complexType name="BookShelf"> 
    <xs:sequence> 
     <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
     <xs:element name="newBook" minOccurs="0" type="xs:string"/> 
     <xs:element name="oldBook" minOccurs="0" type="xs:string"/> 
     </xs:sequence> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

मैं JAXB के साथ इस प्रयास नहीं किया है, लेकिन मुझे लगता है कि यह एक सूची उत्पन्न होगीवर्ग दो फ़ील्ड, नयाबुक और पुराना पुस्तक के साथ। तो, आपको उदाहरण कास्ट या उपयोग करने की ज़रूरत नहीं है, लेकिन यह देखने के लिए कि यह कौन सा है, नल की जांच कर सकते हैं। जैसा कि मैंने कहा, यह एक समाधान है, लेकिन शायद थोड़ा सा करीब है।

-1

मुझे लगता है कि मुझे एक तत्व में विभिन्न तत्वों की सूचियों को मिश्रण करने के विचार को अस्वीकार करना है (एक पुस्तक पर पुरानी और नई किताबें मिलाकर), विशेष रूप से क्योंकि मैं उन तत्वों की सूचियों को संदर्भित करने की योजना बना रहा हूं (नई और पुरानी किताबों की सूचियां) अन्य तत्वों में। अगर मैं जावा कोड में जल्दी से दुःस्वप्न नहीं बनता। मैंने निम्नलिखित स्कीमा के साथ समाप्त किया:

<schema 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://www.example.org/books" 
    targetNamespace="http://www.example.org/books" 
    elementFormDefault="qualified" 
> 
    <complexType name="BookShelf"> 
     <sequence> 
     <element name="newBooks" type="tns:NewBookList" minOccurs="0" /> 
     <element name="oldBooks" type="tns:OldBookList" minOccurs="0" /> 
     </sequence> 
    </complexType> 

    <complexType name="NewBookList"> 
     <sequence> 
     <element name="newBook" type="tns:NewBook" maxOccurs="unbounded" /> 
     </sequence> 
    </complexType> 

    <complexType name="OldBookList"> 
     <sequence> 
     <element name="oldBook" type="tns:OldBook" maxOccurs="unbounded" /> 
     </sequence> 
    </complexType> 

    <complexType name="NewBook" /> 
    <complexType name="OldBook" /> 
</schema> 

सभी को धन्यवाद मुझे यह समझने में मदद करने के लिए धन्यवाद। यह स्कीमा अधिक स्पष्ट और सरल जावा कोड के साथ-साथ अधिक पठनीय और अनुमानित XML दस्तावेज़ तक पहुंच जाएगी।

2

आप JAXB2 Basics से Simplify plugin का उपयोग कर सकते हैं। यह @XmlElements और @XmlElementRefs गुणों को सरल बना सकता है, जो चीजों को वास्तव में पसंद नहीं करते हैं, जो चीजों को बहुत आसान बनाता है।यहाँ एक उदाहरण (प्रलेखन से अंश) है:

<xs:complexType name="typeWithReferencesProperty"> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="a" type="someType"/> 
     <xs:element name="b" type="someType"/> 
    </xs:choice> 
</xs:complexType> 

यह सामान्य रूप से की तरह एक संपत्ति उत्पन्न होगा:

@XmlElementRefs({ 
    @XmlElementRef(name = "a", type = JAXBElement.class), 
    @XmlElementRef(name = "b", type = JAXBElement.class) 
}) 
protected List<JAXBElement<SomeType>> aOrB; 

आप इस फिर से करने के लिए simplify:as-element-property तत्व का उपयोग कर सकते

निम्नलिखित विकल्प पर विचार करें दो गुण गुणों के रूप में जटिल संपत्ति या simplify:as-reference-property दो संदर्भ गुणों के रूप में।

नहीं कि संदर्भ संपत्ति के मामले में, आपको xs:element में से एक को अनुकूलित करना होगा और xs:choice नहीं।

@XmlElement(name = "a") 
protected List<SomeType> a; 
@XmlElement(name = "b") 
protected List<SomeType> b;