从 XSD 文件生成类

问题描述 投票:0回答:2

我尝试使用 JAXB 从 spring-beans.xsd 生成 Java 类(仅用于培训目的),但出现此错误:

parsing a schema...
[ERROR] Property "Ref" is already defined. Use <jaxb:property> to resolve this conflict.
  line 582 of file:/C:/spring-beans.xsd

[ERROR] The following location is relevant to the above error
  line 622 of file:/C:/spring-beans.xsd

[ERROR] Property "Value" is already defined. Use <jaxb:property> to resolve this conflict.
  line 584 of file:/C:/spring-beans.xsd

[ERROR] The following location is relevant to the above error
  line 629 of file:/C:/spring-beans.xsd

[ERROR] Property "Key" is already defined. Use <jaxb:property> to resolve this conflict.
  line 1135 of file:/C:/spring-beans.xsd

[ERROR] The following location is relevant to the above error
  line 1138 of file:/C:/spring-beans.xsd

[ERROR] Property "Ref" is already defined. Use <jaxb:property> to resolve this conflict.
  line 1052 of file:/C:/spring-beans.xsd

[ERROR] The following location is relevant to the above error
  line 1071 of file:/C:/spring-beans.xsd

[ERROR] Property "Value" is already defined. Use <jaxb:property> to resolve this conflict.
  line 1054 of file:/C:/spring-beans.xsd

[ERROR] The following location is relevant to the above error
  line 1078 of file:/C:/spring-beans.xsd

Failed to parse a schema.

怎么了?感谢您提前提供任何帮助。

xml xsd jaxb xjc
2个回答
1
投票

问题在于,在每种情况下,您都有两个 XML 项 - 一个像

这样的元素
<xsd:element ref="ref"/>

和类似

的属性
<xsd:attribute name="ref" type="xsd:string"/>

同一复杂类型。它们都默认映射到名为

Ref
的属性。但由于这两个 XML 项是不同的东西,JAXB 抱怨命名冲突。

解决方案通常非常简单(实际上是由错误日志建议的)。 使用

jaxb:property
绑定自定义属性之一。大致意思是:

<jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jaxb:bindings 
        schemaLocation="spring-beans.xsd" 
        node="/xs:schema">
        <jaxb:bindings node="xs:element[@name='constructor-arg']/xs:complexType/xs:attribute[@name='ref']">
            <jaxb:property name="aRef"/>
        </jaxb:bindings>
    </jaxb:bindings>

</jaxb:bindings>

0
投票

@lexicore 的答案指向了正确的方向。让我给出这个文件的完整解决方案:

  1. 创建重现错误的最小示例:(spring-beans.xsd)
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <xsd:schema xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.springframework.org/schema/beans">
    
        <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
    
        <xsd:element name="constructor-arg">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:choice minOccurs="0" maxOccurs="1">
                        <xsd:element ref="ref"/>
                    </xsd:choice>
                </xsd:sequence>
                <xsd:attribute name="ref" type="xsd:string">
                </xsd:attribute>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="ref">
            <xsd:complexType>
                <xsd:complexContent>
                    <xsd:restriction base="xsd:anyType">
                        <xsd:attribute name="bean" type="xsd:string">
                        </xsd:attribute>
                        <xsd:attribute name="parent" type="xsd:string">
                        </xsd:attribute>
                    </xsd:restriction>
                </xsd:complexContent>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>

1.1 使用 xjc 运行 java 类生成

    xjc .\spring-beans.xsd
    parsing a schema...
    [ERROR] Property "Ref" is already defined. Use &lt;jaxb:property> to resolve this conflict.
      line 13 of file:/D:/xjc/spring-beans.xsd
    
    [ERROR] The following location is relevant to the above error
      line 16 of file:/D:/xjc/spring-beans.xsd
    
    Failed to parse a schema.
  1. 创建绑定以消除错误:(spring-beans-binding.xjb)
    <bindings xmlns="http://java.sun.com/xml/ns/jaxb"
              xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              version="2.1">
            <bindings schemaLocation="spring-beans.xsd" version="1.0">
            <!-- Customise the package name -->
            <schemaBindings>
                <package name="com.example.spring.beans"/>
            </schemaBindings>
    
            <!-- rename the value element -->
            <bindings node="xs:element[@name='constructor-arg']//xs:attribute[@name='ref']">
                <property name="refAttribute"/>
            </bindings>
        </bindings>
    </bindings>

(绑定使用 xpath 来查找 xml 路径。值

xs:element[@name='constructor-arg']//xs:attribute[@name='ref']
表示“匹配顶级元素及其之下的任何级别)

  1. 看到错误已被删除并生成了架构
    xjc .\spring-beans.xsd -b .\spring-beans-binding.xjb
    parsing a schema...
    compiling a schema...
    com\example\spring\beans\ConstructorArg.java
    com\example\spring\beans\ObjectFactory.java
    com\example\spring\beans\Ref.java
    com\example\spring\beans\package-info.java
  1. 将解决方案扩展到整个 spring-beans.xsd 文件
    <bindings xmlns="http://java.sun.com/xml/ns/jaxb"
              xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              version="2.1">
            <bindings schemaLocation="spring-beans.xsd" version="1.0">
            <schemaBindings>
                <package name="com.example.spring.beans"/>
            </schemaBindings>
    
            <bindings node="xs:element[@name='constructor-arg']//xs:attribute[@name='ref']">
                <property name="refAttribute"/>
            </bindings>
            <bindings node="xs:element[@name='constructor-arg']//xs:attribute[@name='value']">
                <property name="valueAttribute"/>
            </bindings>
            <bindings node="xs:complexType[@name='entryType']//xs:attribute[@name='key']">
                <property name="keyAttribute"/>
            </bindings>
            <bindings node="xs:complexType[@name='propertyType']//xs:attribute[@name='ref']">
                <property name="refAttribute"/>
            </bindings>
            <bindings node="xs:complexType[@name='propertyType']//xs:attribute[@name='value']">
                <property name="valueAttribute"/>
            </bindings>
        </bindings>
    </bindings>

4.1 看到schema已经生成了

    xjc .\spring-beans.xsd -b .\spring-beans-binding.xjb
    parsing a schema...
    compiling a schema...
    com\example\spring\beans\Alias.java
    com\example\spring\beans\ArgType.java
    com\example\spring\beans\Array.java
    com\example\spring\beans\Bean.java
    com\example\spring\beans\Beans.java
    com\example\spring\beans\CollectionType.java
    com\example\spring\beans\ConstructorArg.java
    com\example\spring\beans\DefaultableBoolean.java
    com\example\spring\beans\Description.java
    com\example\spring\beans\EntryType.java
    com\example\spring\beans\IdentifiedType.java
    com\example\spring\beans\Idref.java
    com\example\spring\beans\Import.java
    com\example\spring\beans\Key.java
    com\example\spring\beans\List.java
    com\example\spring\beans\ListOrSetType.java
    com\example\spring\beans\LookupMethod.java
    com\example\spring\beans\Map.java
    com\example\spring\beans\MapType.java
    com\example\spring\beans\MetaType.java
    com\example\spring\beans\Null.java
    com\example\spring\beans\ObjectFactory.java
    com\example\spring\beans\Prop.java
    com\example\spring\beans\PropertyType.java
    com\example\spring\beans\Props.java
    com\example\spring\beans\PropsType.java
    com\example\spring\beans\Qualifier.java
    com\example\spring\beans\Ref.java
    com\example\spring\beans\ReplacedMethod.java
    com\example\spring\beans\Set.java
    com\example\spring\beans\Value.java
    com\example\spring\beans\package-info.java

注意xjc是java8提供的

© www.soinside.com 2019 - 2024. All rights reserved.