9

我正在使用 xjc 从 XML 模式生成 Java 类,以下是 XSD 的摘录。

<xs:element name="NameInfo">
  <xs:complexType>
    <xs:sequence>
      <xs:choice>
        <xs:element ref="UnstructuredName"/> <!-- This line -->
        <xs:sequence>
          <xs:element ref="StructuredName"/>
          <xs:element ref="UnstructuredName" minOccurs="0"/> <!-- and this line! -->
        </xs:sequence>
      </xs:choice>
      <xs:element ref="SomethingElse" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

在大多数情况下,生成的类都很好,但对于上面的块,我会得到类似的东西:

public List<Object> getContent() {
  if (content == null) {
    content = new ArrayList<Object>();
  }
  return this.content;
}

上面有以下评论:

* You are getting this "catch-all" property because of the following reason: 
* The field name "UnstructuredName" is used by two different parts of a schema. See: 
* line XXXX of file:FILE.xsd
* line XXXX of file:FILE.xsd
* To get rid of this property, apply a property customization to one 
* of both of the following declarations to change their names: 
* Gets the value of the content property.

我在有问题的两行末尾发表了评论。

目前,我认为更改架构并不容易,因为这是由供应商决定的,我不想走这条路(如果可能的话),因为它会大大减慢进度。

我搜索了,找到了这个页面,外部定制是我想做的吗?我大部分时间都在使用生成的类,所以我并不完全熟悉生成这些类的过程。“属性定制”的简单示例会很棒!只要模式仍然可以使用,生成 Java 类的替代方法就可以了。

编辑:我应该澄清这两者UnstructuredName确实是相同的元素。

4

4 回答 4

5

您还可以使用名为的绑定自定义<xjc:simple />

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              jxb:version="2.0">
        <jxb:globalBindings>
            <xjc:simple />
        </jxb:globalBindings>
</jxb:bindings>

但是请注意,这是特定于供应商的(尽管使用 XJC 以外的其他东西;))

更多信息在这里

于 2012-10-17T08:19:37.563 回答
2

我有同样的问题。我切换到 xmlbeans 和轴。XMLBeans 可以毫无问题地编译您的模式,而且不会让人头疼。JaxB 无法处理这个问题。为了让 JaxB 处理这个问题,您可以稍微更改一下您的架构。

  <xs:sequence>
          <xs:choice>
    <!-- changed the following line -->
            <xs:element name="UnstructuredTop" type="UnstructuredName"/> 
    <!-- end of change -->
            <xs:sequence>
              <xs:element ref="StructuredName"/>
              <xs:element ref="UnstructuredName" minOccurs="0"/>
            </xs:sequence>
          </xs:choice>
          <xs:element ref="SomethingElse" minOccurs="0"/>
    </xs:sequence>

然后JaxB会区分这两者而不是翻转出来。

但是你的情况和我的情况一样。更改架构是不可能的。所以我选择了 xmlBeans 和轴(其中 sux)。

于 2011-03-03T23:08:54.840 回答
1

这里的基本问题是你有一个由一个<xs:sequence>组成的<xs:choice>,它在Java中翻译为“一个List事物”。Java 的类型结构不够灵活,无法更好地表示这一点。

绑定自定义可能会对您有所帮助,但在这种情况下,我怀疑不会,因为我看不到更好的方式来表示此信息。

我过去使用的另一种技术是首先通过一个简单的 XSLT 转换传递模式,将组件重新排列成对 JAXB 更友好的东西,同时仍然允许文档在现实中具有相同的结构。这样,您可以在不更改原始模式的情况下“更改”模式。

于 2010-04-27T08:47:12.153 回答
0

我创建了一个包装类来解决这个问题:

List<JAXBElement<?>> contentList = address.getContent();
if (contentList != null && contentList.size() > 0) {
    Address4JaxbMula address4JaxbMula = new Address4JaxbMula(contentList);

... }

...

public static class Address4JaxbMula {
    public CountryCodeType countryCode;
    public AddressFixType addressFix;
    public String addressFree;

    public Address4JaxbMula(List<JAXBElement<?>> contentList) {
        if (contentList != null && contentList.size() > 0) {
            for (JAXBElement<?> content : contentList) {
                Object value = content.getValue();
                if (value.getClass().isAssignableFrom(CountryCodeType.class)) {
                    countryCode = (CountryCodeType) content.getValue();
                } else if (value.getClass().isAssignableFrom(AddressFixType.class)) {
                    addressFix = (AddressFixType) content.getValue();
                } else {
                    addressFree = (String) value;
                }
            }
        }
    }

}
于 2017-12-18T18:35:54.950 回答