Создавайте классы из xsd и переименовывайте, включая геттеры/сеттеры

#java #kotlin #xsd #jaxb #xjc

Вопрос:

Я пытаюсь создать файлы классов из xsd-файлов в Java 11. Частью используемой схемы является:

   <xs:element name="OptionList">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Option" minOccurs="1" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Description" type="xs:string" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute name="Code" type="xs:string" use="required"/>
            <xs:attribute name="StatusCode" type="xs:string" use="optional"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
 

Когда я генерирую код с помощью плагина из

 <groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
 

Он создает все это в одном файле, как это:

 @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "option"
})
@XmlRootElement(name = "OptionList")
public class OptionList {

    @XmlElement(name = "Option", required = true)
    protected List<OptionList.Option> option;

    public List<OptionList.Option> getOption() {
        if (option == null) {
            option = new ArrayList<OptionList.Option>();
        }
        return this.option;
    }


    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "description"
    })
    public static class Option {

        @XmlElement(name = "Description")
        protected String description;
        @XmlAttribute(name = "Code", namespace = "urn:schema:common:v1", required = true)
        protected String code;
        @XmlAttribute(name = "StatusCode", namespace = "urn:schema:common:v1")
        protected String statusCode;

        public String getDescription() {
            return description;
        }

        public void setDescription(String value) {
            this.description = value;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String value) {
            this.code = value;
        }

        public String getStatusCode() {
            return statusCode;
        }
        public void setStatusCode(String value) {
            this.statusCode = value;
        }

    }

}
 

Мне нужны классы, разделенные на несколько файлов. Я попытался добавить localScoping=»верхний уровень» следующим образом:

 <?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="2.1"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
    <jxb:globalBindings localScoping="toplevel"/>
</jxb:bindings>
 

Это создает объект опции как отдельный класс, но проблема остается в том, что элементы списка опций и получатели/установщики по-прежнему ссылаются на OptionList.Option вместо нового объекта опции. Есть ли способ, которым я могу полностью разделить их при создании и ссылаться на созданный класс? Идеальными созданными файлами были бы следующие:

 @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "option"
})
@XmlRootElement(name = "OptionList")
public class OptionList {

    @XmlElement(name = "Option", required = true)
    protected List<Option> option;

    public List<Option> getOption() {
        if (option == null) {
            option = new ArrayList<Option>();
        }
        return this.option;
    }
}
 
 @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "description"
})
public static class Option {

    @XmlElement(name = "Description")
    protected String description;
    @XmlAttribute(name = "Code", namespace = "urn:schema:common:v1", required = true)
    protected String code;
    @XmlAttribute(name = "StatusCode", namespace = "urn:schema:common:v1")
    protected String statusCode;

    public String getDescription() {
        return description;
    }

    public void setDescription(String value) {
        this.description = value;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String value) {
        this.code = value;
    }

    public String getStatusCode() {
        return statusCode;
    }
    public void setStatusCode(String value) {
        this.statusCode = value;
    }

}
 

Комментарии:

1. Я не знаю ответа, но, возможно, стоит объяснить, зачем вам нужны классы в нескольких файлах. Это может помочь кому-то более точно понять вашу проблему.

2. Разрешено ли переставлять фрагмент XSD в вопросе? Если это так, вы можете удалить вложенный Option элемент, чтобы он находился на том же уровне, OptionList что и элемент.

3. @kimbert Их нужно разделить на несколько классов, потому что мне нужно, чтобы все имена пакетов перед классом были в нижнем регистре. Из — за этого я получаю ошибки.

4. @andrewjames Можно переставить фрагмент XSD, и я сделаю это, если потребуется, но я стараюсь избегать этого, если это вообще возможно.

Ответ №1:

Я не смог придумать, как сделать это так, как хотел. Вместо этого я изменил исходный xsd, чтобы он соответствовал моим потребностям.