【问题标题】:Can Castor handle class generation from multiple XSDs importing from a base XSD?Castor 可以处理从基础 XSD 导入的多个 XSD 的类生成吗?
【发布时间】:2011-12-20 15:03:46
【问题描述】:

我有几个重用相同实体的 XSD。例如,ProductPurchaseRequest.xsdProductQuoteRequest.xsd 的 XSD 中都有一个 <product> 标记来描述相关产品。出于这个原因,我创建了一个Product.xsd 文件来定义<product> 标记,ProductPurchaseRequest.xsdProductQuoteRequest.xsd 都使用`导入Product.xsd

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

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

【问题讨论】:

    标签: java xml ant jaxb castor


    【解决方案1】:

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

    Castor 能做到这一点吗?如果是这样,它的 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>
    

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

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

    更多信息

    【讨论】:

    • 抱歉,我应该指定我最感兴趣的是让它在 Ant 中工作,这就是为什么我发布了我自己的答案,尽管你有如此彻底的回应(我确实赞成)。
    【解决方案2】:

    所以我能够使用 JAXB 参考实现来完成整个工作。诀窍是要意识到从 JAXB site 下载的是 downloader不是实际的库!双击以接受许可证,库将在本地下载。创建了一个测试文件夹(JAXB_TEST)并将所有下载的.jars 复制到lib 子文件夹中。我把我所有的 XSD 放在 XSD 子文件夹中。之后我运行了以下 Ant build.xml 文件。

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

    我遇到的唯一问题是我有一个带有名为 &lt;product&gt; 的根标签的 xsd,它匿名扩展了 Product 类型以添加​​一个 version 属性(我总是喜欢在我的根标签上拥有它)导致 JAXB 的名称冲突。因此,我将匿名类型转换为命名类型(即TopLevelProduct)并将根设置为该类型,JAXB 对此很满意。

    【讨论】:

    • +1 - 所有 Java SE 6 实现中还包含一个 JAXB 实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多