Отображение XML с разными схемами в одни и те же классы с использованием JAXB - PullRequest
1 голос
/ 04 февраля 2020

У меня есть эти два типа XML без предопределенных схем:

A

<root-a>
  <a-item id="a1">
    <name>Name of A1</name>
    <a-item id="a11">
      <name>Name of A11</name>
    </a-item>
    <a-item id="a12">
      <name>Name of A12</name>
      <a-item id="a121">
        <name>Name of A121</name>
      </a-item>
      <a-item id="a122">
        <name>Name of A122</name>
      </a-item>
    </a-item>
  </a-item>
  <a-item id="a2">
    <name>Name of A2</name>
  </a-item>
</root-a>

B

<root-b>
  <b-item id="b1">
    <name>Name of B1</name>
    <b-item id="b11">
      <name>Name of B11</name>
    </b-item>
    <!-- etc., similar to A -->
  </b-item>
</root-b>

Элементы могут быть вложены на произвольную глубину , Структура та же, но имя элемента root и элементов item отличается. Как я могу сопоставить это с единственной Java структурой класса, например. как этот (методы получения и установки отсутствуют) с использованием JAXB:

public class Root {
  private List<Item> items;
}

public class Item {
  private String id;
  private String name;
  private List<Item> items;
}

Я могу отобразить только одну из XML структур, используя аннотации JAXB, но я не знаю, как это сделать, чтобы разместить оба XML в то же время. Я мог бы создать параллельную иерархию для A и B с общим интерфейсом, но я надеюсь, что есть более точное решение.

1 Ответ

0 голосов
/ 13 февраля 2020

Вот схема XML на основе вашего описания:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">

    <!-- Root elements -->
    <xs:element name="root-a" type="rootAType"/>
    <xs:element name="root-b" type="rootBType"/>

    <!-- root-a type -->
    <xs:complexType name="rootAType">
        <xs:sequence>
            <xs:element name="a-item" type="itemAType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <!-- root-b type -->
    <xs:complexType name="rootBType">
        <xs:sequence>
            <xs:element name="b-item" type="itemBType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <!-- abstract item type -->
    <xs:complexType name="itemType" abstract="true">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>

    <!-- item-a type -->
    <xs:complexType name="itemAType">
        <xs:complexContent>
            <xs:extension base="itemType">
                <xs:sequence>
                    <xs:element name="a-item" type="itemAType" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <!-- item-b type -->
    <xs:complexType name="itemBType">
        <xs:complexContent>
            <xs:extension base="itemType">
                <xs:sequence>
                    <xs:element name="b-item" type="itemBType" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>

На основе этой схемы были созданы следующие классы:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "itemType", propOrder = {
    "name"
})
@XmlSeeAlso({
    ItemAType.class,
    ItemBType.class
})
public abstract class ItemType {

    @XmlElement(required = true)
    protected String name;

    @XmlAttribute(name = "id")
    protected String id;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public String getId() {
        return id;
    }

    public void setId(String value) {
        this.id = value;
    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "itemAType", propOrder = {
    "aItem"
})
public class ItemAType
    extends ItemType
{

    @XmlElement(name = "a-item")
    protected List<ItemAType> aItem;

    public List<ItemAType> getAItem() {
        if (aItem == null) {
            aItem = new ArrayList<ItemAType>();
        }
        return this.aItem;
    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "itemBType", propOrder = {
    "bItem"
})
public class ItemBType
    extends ItemType
{

    @XmlElement(name = "b-item")
    protected List<ItemBType> bItem;

    public List<ItemBType> getBItem() {
        if (bItem == null) {
            bItem = new ArrayList<ItemBType>();
        }
        return this.bItem;
    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "rootAType", propOrder = {
    "aItem"
})
public class RootAType {

    @XmlElement(name = "a-item")
    protected List<ItemAType> aItem;

    public List<ItemAType> getAItem() {
        if (aItem == null) {
            aItem = new ArrayList<ItemAType>();
        }
        return this.aItem;
    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "rootBType", propOrder = {
    "bItem"
})
public class RootBType {

    @XmlElement(name = "b-item")
    protected List<ItemBType> bItem;

    public List<ItemBType> getBItem() {
        if (bItem == null) {
            bItem = new ArrayList<ItemBType>();
        }
        return this.bItem;
    }

}

Это кажется слишком сложным , но если у вас есть более общие функциональные возможности между a-item и b-item, структура станет более удобной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...