Схема XML в классы Java с помощью XJC - PullRequest
9 голосов
/ 27 апреля 2010

Я использую xjc для генерации классов Java из схемы XML, и ниже приводится выдержка из 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 ]

5 голосов
/ 17 октября 2012

Вы также можете использовать привязку под названием <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;))

Подробнее здесь

2 голосов
/ 04 марта 2011

У меня была такая же проблема. Я переключился на 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 и axis (который sux).

1 голос
/ 27 апреля 2010

Существенная проблема здесь заключается в том, что у вас есть <xs:sequence>, состоящий из <xs:choice>, что в Java переводится как "List вещей". Структура типов Java недостаточно гибкая, чтобы лучше это представить.

Настройка привязки может помочь вам, но в этом случае, я подозреваю, нет, так как я не вижу лучшего способа представления этой информации.

Альтернативный метод, который я использовал в прошлом, состоит в том, чтобы сначала пройти схему с помощью простого преобразования XSLT, переставив компоненты в нечто более дружественное к JAXB, при этом допуская те же структуры, которые будут иметь документы в реальности. Таким образом, вы можете «изменить» схему без изменения оригинала.

0 голосов
/ 18 декабря 2017

Я создал класс-оболочку для решения проблемы:

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;
                }
            }
        }
    }

}
...