.XSD फ़ाइलों से जावा कक्षाएं उत्पन्न करें ...?


127

मेरे पास एक विशाल क्विकबुक एसडीके .XSD स्कीमा फ़ाइल है जो XML अनुरोधों / प्रतिक्रियाओं को परिभाषित करती है जिसे मैं आईबुक से भेज / प्राप्त कर सकता हूं।

मैं इन .XSD फ़ाइलों से आसानी से जावा कक्षाएं उत्पन्न करने में सक्षम होना चाहता हूं, जो मैं तब XML वस्तुओं को जावा वस्तुओं, और जावा वस्तुओं को XML में मार्शल कर सकता था।

क्या इसे करने का कोई आसान तरीका है...?

आदर्श रूप से, इसे रन-टाइम में मूल जावा डिस्ट्रो के बाहरी किसी भी पुस्तकालय की आवश्यकता नहीं होगी। लेकिन मैं लचीला हूँ ...


6
यदि आप मैनुअल जेनरेशन चाहते हैं, तो अपने एक्सेल प्रोजेक्ट में .xsd फाइल रखें, फाइल पर राइट क्लिक करें, फिर "जेनरेट" हिट करें
Junchen लियू

जवाबों:


121

JAXB वही करता है जो आप चाहते हैं। यह JRE / JDK में 1.6 पर शुरू होता है


7
दुर्भाग्य से, यह कार्यक्षमता अब जावा 9 के रूप में उपलब्ध नहीं होगी। ऐसा इसलिए है क्योंकि इसमें शामिल कक्षाएं (विशेष रूप से, com.sun.tools.xjc। * कक्षाएं) अब JDK के माध्यम से उपलब्ध नहीं होंगी।
मार्को

4
मुझे नहीं लगता कि जेडीके से इसे हटाना एक मुद्दा होना चाहिए, क्योंकि java.net प्रोजेक्ट (जवाब में जुड़ा हुआ) शायद रहने वाला है।
stmoebius

1
जैसा कि यहां बताया गया है , आप कमांड लाइन तर्क द्वारा जावा 9 में निर्भरता जोड़ सकते हैं, या मैन्युअल रूप से निर्भरता जोड़ सकते हैं।
मथायस रेन्ज

118

ऊपर "JAXB" टिप्पणियों का उपयोग करने के लिए,

विंडोज में "%java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd

जैसे, "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

थोड़ा इंतजार करें, और यदि आपके पास एक अच्छी तरह से बनाई गई एक्सएसडी फ़ाइल है, तो आपको कुछ अच्छी तरह से गठित जावा कक्षाएं मिलेंगी


3
बहुत धन्यवाद! एन्कैप्सुलेटेड देखने के बजाय शीर्ष स्तर की कक्षाएं उत्पन्न करने के लिए: stackoverflow.com/questions/13175224/… । और यदि यह वर्ग नाम संघर्ष की ओर जाता है, तो देखें: stackoverflow.com/questions/13414407/…
कल

38

यदि आप 5 मिनट से कम समय में जावा को एक्सएमएल और एक्सएमएल को जावा कोडिंग शुरू करना चाहते हैं, तो सरल एक्सएमएल सीरियलाइजेशन का प्रयास करें। JAXB API सीखने में घंटों खर्च न करें http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

हालांकि, अगर आप वास्तव में JAXB सीखने के लिए उत्सुक हैं, तो यहां एक उत्कृष्ट ट्यूटोरियल है http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

ट्यूटोरियल की सामग्री:

सरल जावा-एक्सएमएल क्रमांकन के लिए JAXB

जावा में XML क्रमांकन करने के कई तरीके हैं। यदि आप पार्सिंग और क्रमांकन पर ठीक-ठीक नियंत्रण चाहते हैं तो आप बेहतर प्रदर्शन के लिए SAX, DOM या Stax के लिए जा सकते हैं। फिर भी, जो मैं अक्सर करना चाहता हूं वह पीओजेओ और एक्सएमएल के बीच एक साधारण मानचित्रण है। हालाँकि, मैन्युअल रूप से XML इवेंट पार्सिंग करने के लिए जावा कक्षाएं बनाना तुच्छ नहीं है। मैंने हाल ही में JAXB को एक त्वरित और सुविधाजनक जावा-एक्सएमएल मैपिंग या धारावाहिककरण के रूप में पाया।

JAXB में बहुत सारी उपयोगी विशेषताएं हैं, आप यहां संदर्भ कार्यान्वयन की जांच कर सकते हैं। JAXB के बारे में अधिक जानने के लिए Kohsuke का ब्लॉग भी एक अच्छा संसाधन है। इस ब्लॉग प्रविष्टि के लिए, मैं आपको दिखाता हूँ कि JAXB के साथ एक सरल जावा-एक्सएमएल क्रमांकन कैसे करें।

XML के लिए POJO

मान लीजिए कि मेरे पास एक आइटम जावा ऑब्जेक्ट है। मैं किसी आइटम ऑब्जेक्ट को XML प्रारूप में क्रमबद्ध करना चाहता हूं। सबसे पहले मुझे जो करना है, वह इस POJO को javax.xml.bind.annotation। से कुछ XML एनोटेशन के साथ करना है। * पैकेज Item.java के लिए कोड सूची 1 देखें

कोड से

  • @XmlRootElement(name="Item") इंगित करता है कि मैं मूल तत्व बनना चाहता हूं।
  • @XmlType(propOrder = {"name", "price"}) उस आदेश को इंगित करता है जो मैं चाहता हूं कि तत्व को एक्सएमएल आउटपुट में व्यवस्थित किया जाए।
  • @XmlAttribute(name="id", ...) इंगित करता है कि आईडी मूल तत्व का एक गुण है।
  • @XmlElement(....) इंगित करता है कि मैं आइटम के भीतर मूल्य और नाम चाहता हूं।

मेरा Item.javaतैयार है। फिर मैं आगे जा सकता हूं और marshaling आइटम के लिए JAXB स्क्रिप्ट बना सकता हूं।

//creating Item data object
Item item = new Item();
item.setId(2);
item.setName("Foo");
item.setPrice(200);
.....

JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
//I want to save the output file to item.xml
marshaller.marshal(item, new FileWriter("item.xml"));

पूर्ण कोड सूचीकरण के लिए कृपया कोड सूची 2 देखें main.java। आउटपुट कोड लिस्टिंग 3 item.xmlफ़ाइल बनाई गई है। यह इस तरह दिख रहा है:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">

 <ns1:itemName>Foo</ns1:itemName>
<ns1:price>200</ns1:price>

</ns1:item>

आसान है ना? आप वैकल्पिक रूप से आउटपुट XML को टेक्स्ट स्ट्रिंग, स्ट्रीम, राइटर, कंटेंटहैंडलर आदि के रूप में चैनल कर सकते हैं, जैसे मार्शाल (...) विधि के पैरामीटर को बदल सकते हैं

...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
// save xml output to the OutputStream instance
marshaller.marshal(item, <java.io.OutputStream instance>);

...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
StringWriter sw = new StringWriter();
//save to StringWriter, you can then call sw.toString() to get java.lang.String
marshaller.marshal(item, sw);

XML करने के लिए POJO

चलो प्रक्रिया को उल्टा करते हैं। मान लें कि मेरे पास अब XML स्ट्रिंग डेटा का एक टुकड़ा है और मैं इसे Item.java ऑब्जेक्ट में बदलना चाहता हूं। XML डेटा (कोड लिस्टिंग 3) जैसा दिखता है

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">
<ns1:itemName>Bar</ns1:itemName>
<ns1:price>80</ns1:price>
</ns1:item>

फिर मैं इस xml कोड को आइटम ऑब्जेक्ट द्वारा अनमर्श कर सकता हूं

...
ByteArrayInputStream xmlContentBytes = new ByteArrayInputStream (xmlContent.getBytes());
JAXBContext context = JAXBContext.newInstance(Item.getClass());
Unmarshaller unmarshaller = context.createUnmarshaller();
//note: setting schema to null will turn validator off
unmarshaller.setSchema(null);
Object xmlObject = Item.getClass().cast(unmarshaller.unmarshal(xmlContentBytes));
return xmlObject;
...

पूर्ण कोड सूची के लिए कृपया कोड सूची 2 (main.java) देखें। XML स्रोत स्ट्रीम और फ़ाइल दोनों से कई रूपों में आ सकता है। एकमात्र अंतर, फिर से, विधि पैरामीटर है:

...
unmarshaller.unmarshal(new File("Item.xml")); // reading from file
...
// inputStream is an instance of java.io.InputStream, reading from stream
unmarshaller.unmarshal(inputStream);

XML स्कीमा के साथ मान्यता

आखिरी बात जो मैं यहां बताना चाहता हूं वह है जावा एक्सएमएल को अनमैर्सॉल करने से पहले स्कीमा के साथ इनपुट एक्सएमएल को मान्य करना। मैं एक XML स्कीमा फ़ाइल बनाता हूं, जिसे item.xsd कहा जाता है। पूर्ण कोड सूची के लिए कृपया कोड सूची 4 (Item.xsd) देखें। अब मुझे जो करना है वह सत्यापन के लिए इस स्कीमा को पंजीकृत करना है।

...
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
.newSchema(new File("Item.xsd"));
unmarshaller.setSchema(schema); //register item.xsd shcema for validation
...

जब मैं POJO के लिए XML डेटा को अनमार्ट करने की कोशिश करता हूं, अगर इनपुट XML स्कीमा के अनुरूप नहीं है, तो अपवाद पकड़ा जाएगा। पूर्ण कोड लिस्टिंग के लिए कृपया कोड सूची 5 (अमान्य_item.xml) देखें।

javax.xml.bind.UnmarshalException
- with linked exception:
javax.xml.bind.JAXBException caught: null
[org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'item1' is
                                not a valid value for 'integer'.]

यहां मैंने पूर्णांक के बजाय स्ट्रिंग में 'आईडी' विशेषता को बदल दिया है।

यदि XML इनपुट स्कीमा के विरुद्ध वैध है, तो XML डेटा को सफलतापूर्वक Item.java ऑब्जेक्ट पर अनमर्श किया जाएगा।


1
यह बहुत ही आशाजनक लग रहा है , और बहुत सरल और अच्छे के साथ काम करने के लिए जो मुझे इसकी आवश्यकता है जैसे कि JAXB जैसे कुछ बड़े और जटिल। दुर्भाग्य से, मैं अपने मौजूदा .XSD को .class फ़ाइलों में परिवर्तित करने का कोई तरीका नहीं देखता, जो कि वास्तव में मुझे शुरू करने की आवश्यकता है। क्या इसे करने का कोई तरीका है?
कीथ पामर जूनियर

7
JAXB ट्यूटोरियल के साथ ब्लॉग Unfortunatelly ऑफ़लाइन है।
लुइस सी।

हम इसे आसानी से jaxb2-maven-plugin का उपयोग करके कर सकते हैं, इस ट्यूटोरियल की जाँच करें journaldev.com/1312/…
पंकज

""% java_home% \ bin \ xjc "-p [आपका नामस्थान] [xsd_file] .xsd" के बारे में क्या जटिल है?
गोरेस्ट

30

ग्रहण आईडीई का उपयोग करना: -

  1. एक नए / मौजूदा प्रोजेक्ट में xsd की प्रतिलिपि बनाएँ।
  2. सुनिश्चित करें कि आपके पास क्लासपैथ में JAXB आवश्यक JARB हैं। आप यहाँ एक डाउनलोड कर सकते हैं
  3. XSD फ़ाइल पर राइट क्लिक करें -> उत्पन्न -> JAXB कक्षाएं।

17

सबसे आसान तरीका कमांड लाइन का उपयोग करना है। बस अपनी .xsd फ़ाइल की निर्देशिका में टाइप करें:

xjc myFile.xsd.

तो, जावा सभी Pojos उत्पन्न करेगा।


14

मावेन का उपयोग इस उद्देश्य के लिए किया जा सकता है, आपको कुछ निर्भरताएं जोड़ने और अपने आवेदन को साफ करने की आवश्यकता है। आपको अपने टार्गेट फोल्डर में सभी कक्षाएं अपने आप मिल जाएंगी।

बस उन्हें लक्ष्य से इच्छित स्थान पर कॉपी करें, यहाँ pom.xml है जिसे मैंने xsd फ़ाइलों से वर्गीकृत करने के लिए उपयोग किया है:

    <plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>jaxb2-maven-plugin</artifactId>

     <executions>
      <execution>
       <goals>
        <goal>xjc</goal>
       </goals>
      </execution>
     </executions>
     <configuration>
      <schemaDirectory>src/main/webapp/schemas/</schemaDirectory>
     </configuration>
    </plugin>

   </plugins>
  </pluginManagement>
 </build>
</project>

बस अपनी xsd फ़ाइलों को "src / main / webapp / schemas /" के नीचे रखें और maven उन्हें संकलन समय पर मिलेगा।

आशा है कि यह आपकी मदद करेगा, अधिक जानकारी http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html पर मिल सकती है

आशा है कि यह मदद करेगा :)


1
क्या यह वास्तव में संसाधन निर्देशिका के साथ काम करता है? (src / main / resource / schemas), क्योंकि मुझे यह मिलता रहता है:No XSD files found. Please check your plugin configuration.
zygimantus

14

XMLBeans करेंगे। विशेष रूप से "scomp" कमांड।

EDIT: XMLBines को सेवानिवृत्त कर दिया गया है , अधिक जानकारी के लिए इस स्टैकओवरफ़्लो पोस्ट की जाँच करें


2
हाँ, लेकिन XMLBeans को बंद कर दिया गया है।
stmoebius


XMLBeans ट्रैक पर वापस आ गया है!
मार्कोलोप्स

7

वैसे सबसे अच्छा विकल्प है %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd

मेरे पास एक सवाल यह भी है कि क्या हमारे पास यहां रिवर्स इंजीनियरिंग करने का विकल्प है। यदि हाँ, तो हम पूजो वर्ग से xsd उत्पन्न कर सकते हैं?


xjc केवल java6
sree

7

यदि आपको बाहरी लाइब्रेरी का उपयोग करने में कोई आपत्ति नहीं है, तो मैंने अतीत में ऐसा करने के लिए कैस्टर का उपयोग किया है।


यदि आप केस्टर के साथ कोड उत्पन्न करते हैं, तो क्या वे उत्पन्न वर्ग अभी भी तथ्य के बाद कॉस्टर पर निर्भर हैं? या मैं कास्टर पुस्तकालयों के बिना उन कक्षाओं को मशीन में स्थानांतरित कर सकता हूं, और वे अभी भी काम करेंगे?
कीथ पामर जूनियर

नहीं, उत्पन्न वर्ग कैस्टर पुस्तकालयों पर निर्भर नहीं हैं।
डेव

क्या ऐसा करने के लिए कैस्टर का उपयोग करने के बारे में कोई अच्छा ट्यूटोरियल है? यह बहुत ही आशाजनक लग रहा है ... लेकिन जावा है, कम से कम कहने के लिए, मेरी सबसे मजबूत भाषा नहीं। मुझे यकीन नहीं है कि कैस्टर फाइलें / पैकेज मुझे डाउनलोड करने की आवश्यकता है और वास्तव में कोड पीढ़ी कैसे करें ... कोई भी चरण-दर-चरण नौसिखिया उदाहरण चारों ओर?
कीथ पामर जूनियर

Castor SourceGenerator वर्ग का उपयोग करने के बारे में प्रलेखन के लिए इस पृष्ठ को देखें: castor.org/sourcegen.html
Marc Novakowski

2
लगता है कि अरंडी लंबे समय से मृत है ... डॉक्स लिंक सभी 404 हैं।
पावेल वेसेलोव

5

JAXB सीमा।

मैंने जेएक्सबी पर काम किया, मेरी राय के अनुसार एक्सएमएल और जावा वस्तुओं के बीच डेटा से निपटने का एक अच्छा तरीका है। सकारात्मक पक्ष इसके सिद्ध होते हैं और रनटाइम के दौरान डेटा पर प्रदर्शन और नियंत्रण में बेहतर होते हैं। निर्मित उपकरणों या लिपियों के एक अच्छे उपयोग के साथ यह कोडिंग प्रयासों को दूर ले जाएगा।

मैंने पाया कि कॉन्फ़िगरेशन भाग एक सीधे दूर का काम नहीं है, और विकास के माहौल को प्राप्त करने में घंटों बिताए हैं।

हालाँकि मैंने इस समाधान को एक मूर्खतापूर्ण सीमा के कारण गिरा दिया जिसका मुझे सामना करना पड़ा। मेरी XML स्कीमा परिभाषा (XSD) में एक विशेषता / तत्व है जिसका नाम "मान" है और मुझे XSD का उपयोग करना है जैसा कि यह है। यह बहुत कम बाधा मेरे बाध्य कदम XJC एक त्रुटि "संपत्ति 'मूल्य' पहले से ही उपयोग के साथ विफल हो गया।"

यह JAXB कार्यान्वयन के कारण है, बाध्यकारी प्रक्रिया प्रत्येक वर्ग में कुछ विशेषताओं को जोड़कर XSD से जावा ऑब्जेक्ट बनाने की कोशिश करती है और उनमें से एक मूल्य विशेषता है। जब इसने मेरे एक्सएसडी को संसाधित किया तो यह शिकायत हुई कि उस नाम के पास पहले से ही एक संपत्ति है।


4

क्या JAXB का XJC इसका संभावित जवाब नहीं है? मैं उसी चीज को हासिल करने की कोशिश कर रहा हूं। हालांकि "कोशिश" चरण में अभी भी। XJC के पार आया, इसलिए साझा करने के बारे में सोचा।



1

JAXB सीमा के बारे में बात करते हुए, अलग-अलग विशेषताओं के लिए एक ही नाम होने पर एक समाधान xdd में इनलाइन jaxb अनुकूलन जोड़ रहा है:

+

। । बाध्यकारी घोषणाएं। ।

या बाहरी अनुकूलन ...

आप और अधिक जानकारी देख सकते हैं: http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.