3

我有几个重用相同实体的 XSD。例如, 和 的 XSD 中ProductPurchaseRequest.xsd都有ProductQuoteRequest.xsd一个<product>标签来描述有问题的产品。出于这个原因,我创建了一个Product.xsd文件来定义 <product>标签和两者,ProductPurchaseRequest.xsd并使用 `.ProductQuoteRequest.xsdProduct.xsd

我想使用 Castor 从这些 XSD 生成 Java 类,并且它们都使用相同的类来表示,Product以便我可以重用相同的逻辑将它们映射到我们模型的ProductModel类。

卡斯特能做到吗?如果是这样,它的 Ant 任务语法是什么。如果不是,也许 JAXB 会是更好的选择吗?

4

2 回答 2

6

注意:我是EclipseLink JAXB (MOXy)负责人,也是JAXB 2 (JSR-222)专家组的成员。

卡斯特能做到吗?如果是这样,它的 Ant 任务语法是什么。如果不是,也许 JAXB 会是更好的选择吗?

以下是如何使用 JAXB 完成此操作的示例:

产品

<?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>

由于多个 XML 模式导入 Product.xsd,我们可以利用情节文件,以便与 Product.xsd 对应的类只生成一次。

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

ProductPurchaseRequest.xsd

下面是导入 Product.xsd 的 XML 模式示例:

<?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>

当我们从这个 XML 模式生成类时,我们将引用我们在从 Product.xsd 生成 Java 类时创建的情节文件。

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

ProductQuoteRequest.xsd

下面是另一个导入 Product.xsd 的 XML 模式示例:

<?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

于 2011-11-02T19:50:30.613 回答
1

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.

于 2011-11-02T21:07:45.297 回答