हम एक्सएमएल पीढ़ी के लिए जेएक्सबी जावा कक्षाएं उत्पन्न करने के लिए एक्सजेसी का उपयोग कर रहे हैं। सब कुछ ठीक काम करता है सिवाय इसके कि हमने जेनरेट किए गए नामस्थान उपसर्गों को समायोजित करने का प्रयास किया जैसा कि यहां बताया गया है. हम जिस JAXB संस्करण का उपयोग कर रहे हैं, उसके कारण हम "समाधान 2" के साथ पैकेज-info.java को समायोजित कर रहे हैं।

हमारे पास जो संरचना है वह कई आयात गहरे हैं: रूट नेमस्पेस अन्य नामस्थान आयात करता है, जो बदले में एक तिहाई आयात करता है।

MCVE xsds

Root.xsd (अन्य आयात करता है। xsd):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="root" xmlns:other="other" targetNamespace="root" version="1.0">
    <xs:import namespace="other" schemaLocation="other.xsd" />
    <xs:element name="rootElem">
        <xs:complexType>
            <xs:choice>
                <xs:element ref="rootElem1"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>
    <xs:element name="rootElem1" nillable="false">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="data">
                    <xs:complexType>
                        <xs:choice>
                            <xs:element ref="other:otherElem"/>
                        </xs:choice>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    </xs:schema>

अन्य.एक्सएसडी (आयात तीसरा। एक्सएसडी):

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:other="other" xmlns:third="third" targetNamespace="other" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
<xsd:import namespace="third" schemaLocation="third.xsd" />
    <xsd:element name="otherElem">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="third:thirdElem" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

तीसरा.एक्सएसडी:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:third="third" targetNamespace="third" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
    <xsd:element name="thirdElem">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="thirdData" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

इसके साथ ही

साधारण परीक्षण मामला

@Test
public void test() throws JAXBException
{
    Marshaller marshaller = JAXBContext.newInstance("test.jaxb.generated").createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.com/schema.xsd");

    RootElem root = new RootElem();
    RootElem1 root1 = new RootElem1();
    Data d = new Data();
    OtherElem other = new OtherElem();
    ThirdElem thirdElem = new ThirdElem();
    thirdElem.setThirdData("third");
    other.setThirdElem(thirdElem);
    d.setOtherElem(other);
    root1.setData(d);
    root.setRootElem1(root1);

    Path path = Paths.get("target", "outfile.xml");

    Result result = new StreamResult(path.toFile());
    marshaller.marshal(root, result);
}

इसका परिणाम यह होता है

उत्पन्न XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:rootElem xmlns:ns2="other" xmlns:ns3="third" xmlns:ns4="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/schema.xsd">
    <ns4:rootElem1>
        <data>
            <ns2:otherElem>
                <ns3:thirdElem>
                    <ns3:thirdData>third</ns3:thirdData>
                </ns3:thirdElem>
            </ns2:otherElem>
        </data>
    </ns4:rootElem1>
</ns4:rootElem>

और सब कुछ ठीक है (data को छोड़कर जिसमें कोई नामस्थान जुड़ा नहीं है, मैं मान रहा हूं क्योंकि यह एक आंतरिक प्रकार है)।

अब यह आंशिक रूप से प्रश्न है: यहाँ है

जनरेट किया गया पैकेज-info.java

@javax.xml.bind.annotation.XmlSchema(namespace = "other", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package test.jaxb.generated;

namespace को other के संदर्भ में क्यों दिया गया है? मेरा रूट नेमस्पेस root है। (root.xsd एकमात्र फाइल है जिसे हम अपना मावेन दे रहे हैं jaxb2-maven-plugin; हम दूसरों को शामिल कर सकते हैं, इससे कोई फर्क नहीं पड़ता)।

गलत प्रतिस्थापन पैकेज-info.java

अगर हम इसके साथ जेनरेट किए गए को ओवरराइट करते हैं:

@javax.xml.bind.annotation.XmlSchema(
        namespace = "root",
        xmlns = {
                @javax.xml.bind.annotation.XmlNs(prefix = "t", namespaceURI = "third"),
                @javax.xml.bind.annotation.XmlNs(prefix = "o", namespaceURI = "other"),
                @javax.xml.bind.annotation.XmlNs(prefix = "r", namespaceURI = "root")
        },
        elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package test.jaxb.generated;

जो हमने शुरू में किया था क्योंकि हमने मान लिया था कि हमें यहां रूट नेमस्पेस देना है - यह है

गलत जेनरेट किया गया XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<r:rootElem xmlns:t="third" xmlns:o="other" xmlns:r="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/schema.xsd">
    <r:rootElem1>
        <data>
            <r:otherElem>
                <t:thirdElem>
                    <t:thirdData>third</t:thirdData>
                </t:thirdElem>
            </r:otherElem>
        </data>
    </r:rootElem1>
</r:rootElem>

अब नामस्थान सुंदर हैं, लेकिन गलत हैं! otherElem, o का है, r का नहीं।

ओवरराइटिंग फ़ाइल में नाम स्थान को वापस other में बदलने से त्रुटि ठीक हो जाती है, लेकिन फिर से:

प्रश्न यह है कि आवश्यक नाम स्थान other यहाँ क्यों है? जिस तरह भ्रमित करने वाला तथ्य यह है कि third आयातित परत किसी भी तरह से सही है।

समस्या ठीक हो गई है, लेकिन हम अवधारणा को समझना चाहेंगे। हम क्या खो रहे हैं?

संपादित करें:

पूर्णता के लिए, मेरे pom.xml का build अनुभाग यहां दिया गया है:

<build>
    <plugins>
        <plugin>
        <!-- run xjc -->
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>xjc-generate_classes</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                    <configuration>
                        <packageName>test.jaxb.generated</packageName>
                        <schemaFiles>
                            root.xsd
                        </schemaFiles>
                        <schemaDirectory>${basedir}/src/main/resources/schemata</schemaDirectory>
                        <extension>true</extension>
                        <bindingDirectory>${basedir}/src/main/resources/bindings</bindingDirectory>
                        <outputDirectory>${basedir}/target/generated-sources/jaxb/</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- overwrite created package-info.java -->
         <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <overwrite>true</overwrite>
                        <outputDirectory>${basedir}/target/generated-sources/jaxb/test/jaxb/generated</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${basedir}/src/main/resources/bindings</directory>
                                <include>package-info.java</include>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
1
daniu 7 जून 2018, 16:27
आप test.jaxb.generated को लक्ष्य पैकेज के रूप में कैसे कॉन्फ़िगर करते हैं?
 – 
lexicore
7 जून 2018, 17:15
पोम.एक्सएमएल में। मैंने इसे पोस्ट में जोड़ा।
 – 
daniu
7 जून 2018, 17:19

1 उत्तर

सबसे बढ़िया उत्तर

समस्या यह है कि आप अपने सभी वर्गों को एक पैकेज में उत्पन्न करते हैं (मेवेन प्लगइन के packageName का उपयोग करके कॉन्फ़िगर किया गया।

यह मत करो।

JAXB कुछ हद तक पैकेज-नेमस्पेस पत्राचार की अवधारणा पर आधारित है। आपके द्वारा उपयोग किए जाने वाले प्रति नामस्थान में एक पैकेज होना चाहिए। जबकि तकनीकी रूप से ऐसा करना संभव है अन्यथा, आपको एक के बाद एक समस्या का सामना करना पड़ेगा। इसलिए इस अवधारणा का पालन करना और प्रति नामस्थान में एक पैकेज का उपयोग करना या उत्पन्न करना बेहतर है। आप अभी भी लक्ष्य संकुल को विन्यस्त कर सकते हैं - लेकिन प्लगइन विन्यास तत्वों के बजाय बाध्यकारी फाइलों का उपयोग कर सकते हैं।

3
lexicore 7 जून 2018, 17:26
लेकिन मैं इसे केवल उसी पैकेज को उत्पन्न करने के लिए कैसे कॉन्फ़िगर कर सकता हूं जिसकी मुझे आवश्यकता है? root.xsd में दिया गया pom.xml पहले से ही आयातित स्कीमा में बेकार है और उनसे कोड उत्पन्न करता है। मैंने आयातित लोगों को अलग से उत्पन्न करने का प्रयास किया, लेकिन इसका परिणाम केवल उस कोड में होता है जिसका उपयोग नहीं किया जाता है (क्योंकि root.xsd द्वारा उत्पन्न कोड केवल उन वर्गों का उपयोग करता है जो इसे स्वयं xjc चलाते हैं)। और अगर मैं पैकेजों को सीमित करने का प्रबंधन करता हूं - root वर्गों को कैसे पता चलेगा कि उन्हें आयात करने की आवश्यकता है?
 – 
daniu
7 जून 2018, 17:30
सुनिश्चित नहीं है कि आपकी समस्या क्या है। आपको यहां तीन पैकेज जेनरेट करने चाहिए, एक नहीं। वह root.xsd अन्य स्कीमा आयात करता है, इससे कोई फर्क नहीं पड़ता। आप बाइंडिंग का उपयोग करके प्रति स्कीमा लक्ष्य पैकेज को अनुकूलित कर सकते हैं। मुझे वास्तव में समस्या नहीं दिख रही है।
 – 
lexicore
7 जून 2018, 17:35
1
यदि आप नाम स्थान के लिए संकुल निर्दिष्ट करना चाहते हैं, हाँ, अनुशंसित तरीका bindings.xjb का उपयोग करना है। प्लगइन में बस packageName कॉन्फिग एलिमेंट को हटा दें (मुझे ऐसा लगता है)। आपको pom.xml (आप नहीं कर सकते) में अलग पैकेज कॉन्फ़िगर करने की आवश्यकता नहीं है, आप इसे bindings.xjb में करते हैं।
 – 
lexicore
7 जून 2018, 17:44
1
यह रहा एक उदाहरण. jaxb:schemaBindings को jaxb:package के साथ देखें, बाकी अप्रासंगिक है।
 – 
lexicore
7 जून 2018, 17:46
1
कुछ विश्लेषण से यह पता लगाया जा सकता है। लेकिन यह इसके लायक नहीं है, मेरी राय में।
 – 
lexicore
7 जून 2018, 17:52