2012-06-11 8 views
15

विफल रहता है मुझे एक्सएसीसी (एक्सएमएल-टू-जावा) कंपाइलर द्वारा एक्सएमएल स्कीमा से उत्पन्न ऑब्जेक्ट मॉडल का आसानी से उपयोग करने के लिए जेएक्सबी का उपयोग करके यह एपीआई मिला है, नामित संदर्भों के माध्यम से। यह जेएक्सबी संदर्भों के निर्माण को सारणीबद्ध करता है और ऑब्जेक्ट फैक्ट्री विधियों को पृष्ठभूमि जादू और प्रतिबिंब के सभी प्रकार से दूर करता है। इसका मूलभूत ज्ञान यह है कि आप हमेशा एक सामान्य स्कीमा को परिभाषित करेंगे, और उसके बाद किसी भी संख्या (0 हो सकती है) स्कीमा "विस्तार" कर सकती है, जो सामान्य है, प्रत्येक के परिणामस्वरूप इसका अपना डेटा मॉडल होता है। सामान्य स्कीमा में पुन: प्रयोज्य परिभाषाएं होती हैं, जो इसे विस्तारित करती हैं, वे अपने स्वयं के मॉडल लिखने के लिए उपयोग करते हैं।एक्सजेसी में आयातित स्कीमा से प्रकार की परिभाषाओं को हल करना

अब मैं उस स्थिति में भाग गया हूं जहां मैं एक से अधिक परियोजनाओं के लिए सामान्य स्कीमा का पुन: उपयोग करना चाहता हूं। सामान्य प्रकार की परिभाषाओं को परियोजनाओं में समान रहना चाहिए, और कुछ कोड उन लोगों से उत्पन्न अमूर्त वर्गों के खिलाफ बनाए जाएंगे। तो मुझे पहले कुछ सामान्य स्कीमा के लिए कक्षाएं उत्पन्न करने की आवश्यकता होगी, फिर उनको उत्पन्न करें और उन्हें अलग से उपयोग करें। मैं अपनी निर्माण प्रक्रिया के लिए मेवेन का उपयोग कर रहा हूँ।

जिस समस्या में मैं चल रहा हूं वह विस्तारित स्कीमा में उस सामान्य स्कीमा से टाइप परिभाषाओं को हल कर रहा है।

मान लीजिए मेरी सामान्य स्कीमा "general.xsd" नाम और इस तरह दिखता है:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.foobar.com/general" 
xmlns:gen="http://www.foobar.com/general" 
elementFormDefault="qualified" attributeFormDefault="qualified"> 

    <!-- Element (will usually be root) --> 
    <xs:element name="transmission" type="gen:Transmission" /> 

    <!-- Definition --> 
    <xs:complexType name="Transmission" abstract="true"> 
     <xs:sequence> 
      <!-- Generic parts of a transmission would be in here... --> 
     </xs:sequence> 
    </xs:complexType> 

</xs:schema> 

यह है कि एक बाइंडिंग कुछ नामकरण अनुकूलन कर सकते हैं और उत्पादन के लिए पैकेज का नाम स्थापित करने के लिए फाइल करने के लिए अगला:

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb21-plugin</artifactId> 
    <version>0.8.0</version> 
    <executions> 
     <execution> 
      <id>xjc-generate</id> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
      <configuration> 
       <schemaDirectory>${basedir}/src/main/resources/com/foobar/schemas</schemaDirectory> 
       <schemaLanguage>XMLSCHEMA</schemaLanguage> 
       <addCompileSourceRoot>true</addCompileSourceRoot> 
       <episode>true</episode> 
       <removeOldOutput>true</removeOldOutput> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 
:

<?xml version="1.0" encoding="UTF-8"?> 
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd" 
    version="2.1"> 

    <!-- Bindings for the general schema --> 
    <bindings schemaLocation="general.xsd" node="/xs:schema"> 

     <schemaBindings> 
      <package name="com.foobar.models.general"/> 
     </schemaBindings> 

     <bindings node="//xs:complexType[@name='Transmission']"> 
      <!-- Some customization of property names here... --> 
     </bindings> 

</bindings> 

मैं तो उस परियोजना जावा वर्गों उत्पन्न करने के लिए की पोम में अगले सा होगा

जैसा कि आप देख सकते हैं, मैं JAXB2.1 मेवेन प्लगइन का उपयोग कर रहा हूं। मैंने चरणबद्ध संकलन के लिए उत्पन्न एपिसोड फ़ाइल रखने का विकल्प सेट किया है। पिछले आउटपुट को हटाने का विकल्प बग वर्कअराउंड के लिए था; यह सब कुछ सुनिश्चित करता है कि सबकुछ पहले साफ हो गया है इसलिए पुन: संकलन मजबूर हो गया है।

अभी तक इतना अच्छा है। वह परियोजना बिना छेड़छाड़ के संकलित करती है। यह ध्यान दिया जाना चाहिए कि उत्पन्न जावा कक्षाओं के अलावा, मैं स्कीमा को परिणामी जार फ़ाइल में भी पैकेज करता हूं। तो वे कक्षा में उपलब्ध हैं! sun-jaxb.episode फ़ाइल मेटा-आईएनएफ में है, जैसा कि यह होना चाहिए।

फिर मैं उस परियोजना को शुरू करता हूं जो स्कीमा का उपयोग करता है जो इसे पहले आयात करके उपरोक्त बढ़ाएगा। "उपप्रकार" में से एक (मैं इसे sub.xsd फोन करता हूँ) ऐसा दिखाई दे सकता:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.foobar.com/sub" 
xmlns:sub="http://www.foobar.com/sub" 
xmlns:gen="http://www.foobar.com/general" 
elementFormDefault="qualified" attributeFormDefault="qualified"> 

    <xs:import namespace="http://www.foobar.com/general" /> 

    <!-- Definition --> 
    <xs:complexType name="SubTransmission"> 
     <xs:complexContent> 
      <xs:extension base="gen:Transmission"> 
       <xs:sequence> 
        <!-- Additional elements placed here... --> 
       </xs:sequence> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

</xs:schema> 

फिर, वहाँ एक बाइंडिंग फ़ाइल है:

<?xml version="1.0" encoding="UTF-8"?> 
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd" 
    version="2.1"> 

    <!-- Bindings for sub type --> 
    <bindings schemaLocation="sub.xsd" node="/xs:schema"> 

     <schemaBindings> 
      <package name="com.foobar.models.sub"/> 
     </schemaBindings> 

    </bindings> 

</bindings> 

और यहाँ की पोम से सा इस परियोजना है कि XJC पीढ़ी का ख्याल रखता है: मूलतः

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb21-plugin</artifactId> 
    <version>0.8.0</version> 
    <executions> 
     <execution> 
      <id>xjc-generate</id> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
      <configuration> 
       <schemaDirectory>${basedir}/src/main/resources/com/foobar/schemas</schemaDirectory> 
       <schemaLanguage>XMLSCHEMA</schemaLanguage> 
       <addCompileSourceRoot>true</addCompileSourceRoot> 
       <episode>false</episode> 
       <catalog>${basedir}/src/main/resources/com/foobar/schemas/catalog.cat</catalog> 
       <episodes> 
        <episode> 
         <groupId>com.foobar</groupId> 
         <artifactId>foobar-general-models</artifactId> 
         <version>1.0.0-SNAPSHOT</version> 
         <scope>compile</scope> 
        </episode> 
       </episodes> 
       <removeOldOutput>true</removeOldOutput> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

, सभी स्कीमा एक ही फ़ोल्डर में थे और मैं general.xsd करने के लिए सेट आयात में schemaLocation विशेषता है, जो worke था ठीक है लेकिन अब ये चीजें परियोजनाओं में अलग हो गई हैं, मैं समस्याओं में भाग लेता हूं। पहला मुद्दा यह था कि अन्य स्कीमा नहीं मिला। मैंने तत्व <xs:import /> तत्व से बाहर निकालने के द्वारा इसे हल किया है, केवल namespace विशेषता रखें और एक कैटलॉग फ़ाइल (catalog.cat) जोड़ना जो आप उपर्युक्त पीओएम निकालने में संदर्भित देख सकते हैं।इसकी सामग्री हैं:

PUBLIC "http://www.foobar.com/general" "classpath:/com/foobar/schemas/general.xsd" 

ऐसा लगता है, क्योंकि अब मुझे कोई त्रुटि नहीं मिलती है जो स्कीमा नहीं मिल सकती है। लेकिन किसी कारण से, आयातित स्कीमा से वास्तविक प्रकार की परिभाषाओं को हल करना जारी रहता है। यहाँ अपवाद है:

Error while parsing schema(s).Location [ file:/C:/NetBeans_groups/Test/SubModelBundle/src/main/resources/com/foobar/schemas/sub.xsd{...,...}]. 
org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'gen:Transmission' to a(n) 'type definition' component. 

यहाँ मैं अब तक की कोशिश की है:

  • एक सूची फ़ाइल का उपयोग करें। आंशिक रूप से सफल, क्योंकि आयातित स्कीमा अब पाया जा सकता है।
  • सामान्य स्कीमा के लिए संकलन एक एपिसोड फ़ाइल उत्पन्न करता है और उप स्कीमा के संकलन के लिए इसका उपयोग करता है। एक फर्क नहीं पड़ता है, हालांकि इस प्रकार को हल करने के बाद ही इसे एक भूमिका निभानी चाहिए, इसलिए मुझे नहीं लगता कि यह अभी भी महत्वपूर्ण है।
  • एक अलग जेएक्सपी (नोट: जेएक्सबी, जेएक्सपी) कार्यान्वयन का उपयोग करें। यह एक अलग का उपयोग करता था, क्योंकि मैं देख सकता था कि अपवाद के स्टैक ट्रेस में, लेकिन अंतिम परिणाम वही है।
  • 21 के बजाय maven-jaxb22-plugin का उपयोग करें। कोई फर्क नहीं पड़ता।

ऑनलाइन देख रहे हैं, ऐसा लगता है कि लोग कम से कम 2006 के बाद से इस मुद्दे में भाग रहे हैं और यह कुछ ज़ीरस रिज़ॉल्वर समस्याओं से संबंधित हो सकता है। मुझे उम्मीद है कि यह कुछ बग नहीं है जो इसे ठीक करने की देखभाल किए बिना 6 साल तक छिप रहा है। क्या किसी और के पास कुछ सुझाव हैं? शायद कोई एक ही समस्या में भाग गया और समाधान मिला? एकमात्र कामकाज मैं सोच सकता हूं कि सामान्य स्कीमा को उप प्रोजेक्ट में खींचने के लिए 'svn: externals' का उपयोग करना है और केवल कक्षाओं को पुन: उत्पन्न करना है, लेकिन यह गंदा है और केवल तभी काम करेगा जब आप हमारे svn repo से कनेक्ट कर सकते हैं।

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

+0

मैं एक ही समस्याएं आ रही हैं में Maven 3 परिणामों के साथ इस विन्यास काम करना:

यहां एक नमूना विन्यास है। एक अच्छी तरह से प्रलेखित प्रश्न के लिए +1। – KingAndrew

उत्तर

4

यह उत्तर संपादित किया गया था। इससे पहले, मेरे पास कस्टम कैटलॉग रिज़ॉल्वर का उपयोग करके समाधान था। हालांकि, मुझे अब वास्तविक समस्या मिली है। स्पष्टीकरण निम्नानुसार है। टीएल के लिए; डीआर संस्करण जो समाधान प्रदान करता है, इस उत्तर के नीचे स्क्रॉल करें।


समस्या सूची फ़ाइल के साथ है। ध्यान दें कि यह लाइन कैसे थी:

PUBLIC "http://www.foobar.com/general" "classpath:/com/foobar/schemas/general.xsd" 

यह क्या कहता है? यह कहता है कि यदि सार्वजनिक आईडी http://www.foobar.com/general का सामना करना पड़ता है, तो स्कीमा के लिए सिस्टम आईडी classpath:/com/foobar/schemas/general.xsd है। अब तक सब ठीक है। यदि हम schemaLocation हमारे <xs:import /> तत्वों में से विशेषता देते हैं, तो केवल एक चीज जो बनी हुई है वह सार्वजनिक आईडी (नेमस्पेस यूआरएन) है और कैटलॉग फ़ाइल हमें बताती है कि इसके लिए स्कीमा कहां मिलें।

समस्या तब होती है जब उस स्कीमा में <xs:include /> तत्वों का उपयोग किया जाता है। उनमें एक ही लक्ष्य नामस्थान के साथ स्कीमा फ़ाइलें शामिल हैं। वे एक सिस्टम आईडी (सापेक्ष स्थान) निर्दिष्ट करते हैं। तो आप उम्मीद करेंगे कि संकल्प के लिए इस्तेमाल किया जाएगा। हालांकि, कैटलॉग रिज़ॉल्वर को कॉल लॉगिंग से पता चलता है कि सार्वजनिक आईडी (नेमस्पेस) और सिस्टम आईडी (सापेक्ष स्थान) दोनों के साथ रिज़ॉल्यूशन के लिए अनुरोध किए गए हैं। और यही वह जगह है जहां यह गलत हो जाता है। कैटलॉग फ़ाइल में बाध्यकारी होने के कारण सार्वजनिक आईडी को वरीयता दी जाती है। और यह हमें सीधे general.xsd फ़ाइल पर ले जाता है।

कहते हैं, उदाहरण के लिए सामान्य स्कीमा इस प्रकार है कि:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.foobar.com/general" 
xmlns:gen="http://www.foobar.com/general" 
elementFormDefault="qualified" attributeFormDefault="qualified"> 

    <!-- Including some definitions from another schema in the same location --> 
    <xs:include schemaLocation="simple-types.xsd" /> 

    <!-- Remaining stuff... --> 

</xs:schema> 

और वह एक स्कीमा का उपयोग कर एक प्रकार है कि:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.foobar.com/sub" 
xmlns:sub="http://www.foobar.com/sub" 
xmlns:gen="http://www.foobar.com/general" 
elementFormDefault="qualified" attributeFormDefault="qualified"> 

    <xs:import namespace="http://www.foobar.com/general" /> 

    <!-- Remaining stuff... --> 

</xs:schema> 

जब XJC कि पिछले स्कीमा को पार्स किया जाता है, यह है हो रहा है:

  1. स्थानीय परिभाषाओं को पार्स करना।
  2. से परिभाषा के संदर्भ में Encounters स्कीमा आयात किया गया।
  3. आयात की जांच करता है, कोई सिस्टम आईडी नहीं, केवल सार्वजनिक आईडी (http://www.foobar.com/general) पाता है।
  4. चेक कैटलॉग (ओं)।
  5. classpath:/com/foobar/schemas/general.xsd पर सार्वजनिक आईडी का बाध्यकारी ढूंढता है।
  6. आयातित स्कीमा में पार्सिंग परिभाषाएं।
  7. से परिभाषा के संदर्भ में Encounters स्कीमा (सरल-प्रकार.एक्सएसडी) शामिल थे।
  8. चेक में शामिल हैं, सिस्टम आईडी पाता है।
  9. सिस्टम आईडी के लिए चेक कैटलॉग (ओं), लेकिन सार्वजनिक आईडी निहित है।
  10. classpath:/com/foobar/schemas/general.xsd पर सार्वजनिक आईडी का बाध्यकारी ढूंढता है, जो सिस्टम आईडी पर वरीयता लेता है।
  11. स्कीमा परिभाषाओं का संकल्प विफल रहता है।

एक्सएमएल कैटलॉग के लिए ओएएसआईएस स्पेक में जिस क्रम में संकल्प का प्रयास किया गया है, उसके विवरण का वर्णन किया गया है: https://www.oasis-open.org/committees/entity/spec.html#s.ext.ent। इसमें थोड़ा सा व्याख्या होती है, लेकिन आप पाएंगे कि यदि संकल्प की पसंदीदा विधि सार्वजनिक आईडी है, तो सिस्टम आईडी होने पर भी कैटलॉग फ़ाइल में बाध्य होने पर उन्हें प्राथमिकता दी जाएगी।

समाधान यह निर्दिष्ट करना है कि सिस्टम आईडी संकल्प की पसंदीदा विधि है, आयात में सिस्टम आईडी प्रदान नहीं करती है ताकि कैटलॉग की सार्वजनिक आईडी बाध्यकारी का उपयोग किया जा सके और इसमें शामिल रिश्तेदार सिस्टम आईडी पर निर्भर किया जा सके। ओएएसआईएस एक्सएमएल कैटलॉग प्रारूप में, आप विशेषता prefer="system" का उपयोग कर सकते हैं। ओएएसआईएस TR9401 कैटलॉग प्रारूप में, आप OVERRIDE no का उपयोग कर सकते हैं। स्पष्ट रूप से डिफ़ॉल्ट सार्वजनिक/हां है।

तो मेरी सूची फ़ाइल तो हो जाता है:

OVERRIDE no 
PUBLIC "http://www.foobar.com/general" "classpath:/com/foobar/schemas/general.xsd" 

अब नियमित रूप से सूची समाधानकर्ता ठीक काम करता है। अब मुझे कस्टम की जरूरत नहीं है। हालांकि, मैंने अनुमान नहीं लगाया होगा कि स्कीमा समेत संकल्प के लिए सार्वजनिक आईडी अभी भी उपयोग की जाती है और सिस्टम आईडी पर प्राथमिकता लेती है। मैंने सोचा होगा कि सार्वजनिक आईडी का उपयोग केवल आयात के लिए किया जाएगा, और अगर संकल्प विफल हुआ तो सिस्टम आईडी पर अभी भी विचार किया जाएगा। कस्टम रिज़ॉल्वर को केवल कुछ लॉगिंग जोड़ने से यह पता चला।


संक्षिप्त उत्तर: OVERRIDE no अपने TR9401 सूची फ़ाइल में पहली निर्देश के रूप में जोड़ सकते हैं या एक एक्सएमएल फाइल करने के लिए सूची prefer="system" जोड़कर देखते हैं। <xs:import /> निर्देशों में schemaLocation निर्दिष्ट न करें, लेकिन कैटलॉग फ़ाइल में उचित स्कीमा स्थान पर नामस्थान को बाध्य करें। सुनिश्चित करें कि <xs:include /> शामिल स्कीमा के सापेक्ष पथ का उपयोग करता है।

एक और दिलचस्प बात: एक्सजेसी द्वारा उपयोग किए जाने वाले कैटलॉग रिज़ॉल्वर न केवल classpath: यूआरआई को संभाल सकता है, लेकिन maven: यूआरआई, जो मेवेन आर्टेफैक्ट के सापेक्ष काम करता है। अगर आप इसे अपने निर्माण उपकरण के रूप में उपयोग कर रहे हैं तो बहुत उपयोगी। http://confluence.highsource.org/display/MJIIP/User+Guide#UserGuide-Usingcatalogs

2

मुझे org.jvnet.jaxb2.maven2.resolver.tools.ClasspathCatalogResolver प्रयोग करने के लिए Maven 2.2.1 काम करता है का उपयोग करना।

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <version>0.8.0</version> 
    <executions> 
     <execution> 
      <id>executionId</id> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
      <configuration> 
       <schemaDirectory>src/main/resources/META-INF/schemas</schemaDirectory> 
       <generatePackage>com.company.project.data</generatePackage> 
       <bindingDirectory>src/main/jaxb</bindingDirectory> 
       <catalog>src/main/jaxb/catalog.cat</catalog> 
       <catalogResolver>org.jvnet.jaxb2.maven2.resolver.tools.ClasspathCatalogResolver</catalogResolver> 
       <verbose>false</verbose> 
       <extension>true</extension> 
       <episodes> 
        <episode> 
         <groupId>com.company.project</groupId> 
         <artifactId>xsd-common-types</artifactId> 
         <version>${xsd-common-types.version}</version> 
        </episode> 
       </episodes> 
      </configuration> 
     </execution> 
    </executions> 
    <dependencies> 
     <dependency> 
      <groupId>com.company.project</groupId> 
      <artifactId>xsd-common-types</artifactId> 
      <version>${xsd-common-types.version}</version> 
     </dependency> 
    </dependencies> 
</plugin> 

एक org.xml.sax.SAXParseException

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