Как сгенерировать Java из XSD-файлов, используя JAXB, когда одно и то же имя поля используется дважды в xs: choice? - PullRequest
0 голосов
/ 06 июля 2018

У меня есть проект Java maven, и мне нужно сгенерировать классы Java из коллекции файлов XSD. Я использую jaxb2-maven-плагин 2.4. Один из файлов XSD содержит этот фрагмент:

<xs:choice>
    <xs:sequence>
        <xs:element name="LOT_DIVISION" type="lot_division_f01"/>
        <xs:element name="OBJECT_DESCR" type="object_f01"/>
    </xs:sequence>
    <xs:sequence>
        <xs:element ref="NO_LOT_DIVISION"/>
        <xs:element name="OBJECT_DESCR" type="object_f01"/>
    </xs:sequence>
</xs:choice>

Когда я пытаюсь автоматически сгенерировать Java-классы для этого, используя JAXB, я получаю что-то вроде этого:

<code>/**
 * Gets the rest of the content model. 
 * 
 * <p>
 * You are getting this "catch-all" property because of the following reason: 
 * The field name "OBJECTDESCR" is used by two different parts of a schema. See: 
 * line 142 of file:/C:/Projects/main/web/service/src/xsd/ted/209/F01_2014.xsd
 * line 138 of file:/C:/Projects/main/web/service/src/xsd/ted/209/F01_2014.xsd
 * <p>
 * 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.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the content property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getContent().add(newItem);
 * 
* * *

* Объекты следующих типов разрешены в списке * {@link JAXBElement} {@ code <} {@ link TextFtSingleLine} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link CpvSet} {@ code>} * {@link JAXBElement} {@ code <} {@ link TypeContract} {@ code>} * {@link JAXBElement} {@ code <} {@ link TextFtMultiLines} {@ code>} * {@link JAXBElement} {@ code <} {@ link Val} {@ code>} * {@link JAXBElement} {@ code <} {@ link LotDivisionF01} {@ code>} * {@link JAXBElement} {@ code <} {@ link ObjectF01} {@ code>} * {@link JAXBElement} {@ code <} {@ link Пусто} {@ code>} * {@link JAXBElement} {@ code <} {@ link XMLGregorianCalendar} {@ code>} * * * / публичный список > getContent () { if (content == null) { content = new ArrayList > (); } вернуть this.content; }

Я ожидал геттера для каждого свойства, но вместо этого я получаю этот полный кошмар кошмар.

В нем говорится, что это потому, что OBJECTDESCR используется в 2 разных частях схемы, и это правильно. И обычно я просто использовал бы bindings.xjb для переименования одного или другого, но я не понимаю, как в этом случае.

Данные XML и файлы XSD взяты из http://ftp.ted.europa.eu/TED/main/HomePage.do, поэтому я немного контролирую эти части. Но мне нужно прочитать их данные.

Вся коллекция файлов XSD доступна здесь: http://publications.europa.eu/mdr/resource/eprocurement/ted/R2.0.9/publication/latest/, фрагмент кода F01_2014.xsd.

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Кто-то опубликовал здесь ответ, в котором говорится, что я должен попробовать что-то подобное в моих привязках. Xjb:

<jxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jxb:bindings>
        <jxb:globalBindings choiceContentProperty="true"/>
    </jxb:bindings>
</jxb:bindings>

Я не знаю, где этот ответ пошел, но я попробовал то, что он предложил, и это сработало. Это сработало так хорошо, что я смог удалить все остальные привязки jxb: Так что спасибо, кто бы это ни был. Это был бы мой принятый ответ.

0 голосов
/ 06 июля 2018

Отказ от ответственности: Я являюсь автором JAXB2 Simplify Plugin , который может выполнять эту работу.

Давайте начнем с MCVE:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="choice" type="choiceType"/>
    <xs:complexType name="choiceType">
        <xs:choice>
            <xs:sequence>
                <xs:element name="x" type="xs:string"/>
                <xs:element name="z" type="xs:string"/>
            </xs:sequence>
            <xs:sequence>
                <xs:element name="y" type="xs:string"/>
                <xs:element name="z" type="xs:string"/>
            </xs:sequence>
        </xs:choice>
    </xs:complexType>
</xs:schema>

В результате получается такой код:

@XmlElementRefs({
    @XmlElementRef(name = "x", type = JAXBElement.class, required = false),
    @XmlElementRef(name = "z", type = JAXBElement.class, required = false),
    @XmlElementRef(name = "y", type = JAXBElement.class, required = false)
})
protected List<JAXBElement<String>> xAndZOrY;

Хотя этот код может быть лучше с точки зрения моделирования, он выглядит странно, и большинство разработчиков предпочли бы что-нибудь попроще.Как три отдельных свойства x, y и z.

. Для этого вы можете использовать JAXB2 Simplify Plugin .Вот как это делается.

Сначала добавьте JAXB2 Simplify Plugin к генерации кода JAXB.См. это руководство это будет выглядеть следующим образом:

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.14.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <args>
                    <arg>-Xsimplify</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics</artifactId>
                        <version>0.12.0</version>
                    </plugin>
                </plugins>
            </configuration>
        </plugin>

Извините, я не буду приводить конфигурации для других плагинов JAXB2 Maven здесь (например, ).

Далее необходимо указать плагин Simplify, свойство которого вы хотите упростить.Это может быть сделано либо непосредственно в схеме, либо (предпочтительным образом) через внешний файл привязки:

<jaxb:bindings
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
    jaxb:extensionBindingPrefixes="simplify"
    jaxb:version="2.3">

    <jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
        <jaxb:bindings node="xsd:complexType[@name='choiceType']">
            <simplify:property name="xAndZOrY">
                <simplify:as-element-property/>
            </simplify:property>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

Это приводит к следующему коду:

protected List<String> x;
protected List<String> z;
protected List<String> y;

public List<String> getX() { ... }

public List<String> getZ() { ... }

public List<String> getY() { ... }

Вы можете найти полный рабочийпример здесь:

https://github.com/highsource/jaxb2-basics-support/tree/master/s/simplify-choice

...