Can Castor handle class generation from multiple XSDs importing from a base XSD?

前端 未结 2 573
臣服心动
臣服心动 2020-12-11 10:31

I have several XSDs that reuse the same entities. For example, both the XSDs for the ProductPurchaseRequest.xsd and ProductQuoteRequest.xsd both ha

相关标签:
2条回答
  • 2020-12-11 10:39

    So I was able to get the whole thing working using the JAXB reference implementation. The trick was to realise that the download from JAXB site is a downloader and not the actual libraries! Double-click to accept the licence and the libraries will download locally. Created a test folder (JAXB_TEST) and copied all the downloaded .jars to a lib subfolder. I put all my XSDs in XSD subfolder. After that I ran the following Ant build.xml file.

    <?xml version="1.0"?>
    <project name="jaxb_test" basedir="." default="package" >
    
        <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
            <classpath>
                <fileset dir="./lib" includes="*.jar" />
            </classpath>
        </taskdef>
    
        <target name="generate">
            <delete dir="./gen-src" />
            <mkdir dir="./gen-src" />
    
            <xjc destdir="./gen-src" language="XMLSCHEMA" package="com.mmm" >
                <schema dir="./xsd" includes="EPC*.xsd" />
            </xjc>      
        </target>
    
        <target name="compile" depends="generate" >
            <delete dir="./bin" />
            <mkdir dir="./bin" />
    
            <javac srcdir="./gen-src" destdir="./bin" includeantruntime="false" />
        </target>
    
        <target name="package" depends="compile" >
            <delete dir="./dist" />
            <mkdir dir="./dist" />
            <jar destfile="./dist/jaxb-gen.jar" basedir="./bin" />
        </target>   
    
    
    </project>
    

    The only problem I had was that I had an xsd with a root tag called <product> that anonymous extended the Product type to add a version attribute (which I always like to have on my root tag's) which was causing a name conflict for JAXB. So instead, I turned the anonymous type into a named type (i.e. TopLevelProduct) and set the root to that type and JAXB was happy with that.

    0 讨论(0)
  • 2020-12-11 10:49

    Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.

    Can Castor do this? If so, what would be the Ant task syntax for it. If not, would perhaps JAXB be a better alternative?

    Below is an example of how this could be done using JAXB:

    Product

    <?xml version="1.0" encoding="UTF-8"?>
    <schema 
        xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.org/Product" 
        xmlns:tns="http://www.example.org/Product" 
        elementFormDefault="qualified">
        <element name="product">
            <complexType>
                <sequence>
                    <element name="id" type="string"/>
                    <element name="name" type="string"/>
                </sequence>
            </complexType>
        </element>
    </schema>
    

    Since multiple XML schemas import Product.xsd we can leverage episode files so that the classes corresponding to Product.xsd are only generated once.

    xjc -d out -episode product.episode Product.xsd
    

    ProductPurchaseRequest.xsd

    Below is an example of an XML schema that imports Product.xsd:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema 
        xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.org/ProductPurchaseRequest" 
        xmlns:tns="http://www.example.org/ProductPurchaseRequest"
        xmlns:prod="http://www.example.org/Product" 
        elementFormDefault="qualified">
        <import namespace="http://www.example.org/Product" schemaLocation="Product.xsd"/>
        <element name="purchase-request">
            <complexType>
                <sequence>
                    <element ref="prod:product" maxOccurs="unbounded"/>
                </sequence>
            </complexType>
        </element>
    </schema>
    

    When we generate classes from this XML schema we will reference the episode file we created when we generated Java classes from Product.xsd.

    xjc -d out ProductPurchaseRequest.xsd -extension -b product.episode
    

    ProductQuoteRequest.xsd

    Below is another example of an XML schema that imports Product.xsd:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema 
        xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.org/ProductQuoteRequest" 
        xmlns:tns="http://www.example.org/ProductQuoteRequest" 
        xmlns:prod="http://www.example.org/Product" 
        elementFormDefault="qualified">
        <import namespace="http://www.example.org/Product" schemaLocation="Product.xsd"/>
        <element name="quote">
            <complexType>
                <sequence>
                    <element ref="prod:product"/>
                </sequence>
            </complexType>
        </element>
    </schema>
    

    Again when we generate classes from this XML schema we will reference the episode file we created when we generated Java classes from Product.xsd.

    xjc -d out ProductQuoteRequest.xsd -extension -b product.episode
    

    For More Information

    • http://weblogs.java.net/blog/kohsuke/archive/2006/09/separate_compil.html
    0 讨论(0)
提交回复
热议问题