Реализация JAXB (JSR-222) позаботится обо всем для вас. JAXB считает, что каждый класс соответствует сложному типу. Он имеет алгоритм для определения имени типа, но вы можете переопределить его, используя аннотацию @XmlType
. Когда элемент неармаллирован, если он содержит атрибут xsi:type
, тогда JAXB будет смотреть, есть ли класс, связанный с этим типом. Если есть, он будет создавать экземпляр класса этого типа, если он не будет создавать экземпляр типа, соответствующего этому элементу, на основе метаданных отображения, предоставленных через аннотации.
Для получения более подробной информации
UPDATE
Ниже приведен пример, который может помочь:
schema.xsd
В схеме XML ниже сложного типа canadianAddress
расширяет ComplexType address
.
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/customer"
xmlns:tns="http://www.example.org/customer"
elementFormDefault="qualified">
<element name="customer">
<complexType>
<sequence>
<element name="address" type="tns:address"/>
</sequence>
</complexType>
</element>
<complexType name="address">
<sequence>
<element name="street" type="string"/>
</sequence>
</complexType>
<complexType name="canadianAddress">
<complexContent>
<extension base="tns:address">
<sequence>
<element name="postalCode" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
Demo
В демо-коде ниже XML будет преобразован в модель JAXB генерируется из приведенных выше схем XML, а затем преобразуется обратно в XML.
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance("org.example.customer");
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/org/example/customer/input.xml");
Customer customer = (Customer) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
}
Input.xml/Выход
Ниже XML. Элемент address
имеет xsi:type
, чтобы указать, что он содержит экземпляр canadianAddress
, а не только address
.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer xmlns="http://www.example.org/customer">
<address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="canadianAddress">
<street>1 A Street</street>
<postalCode>Ontario</postalCode>
</address>
</customer>
На самом деле я проверил вашу статью в блоге перед публикацией здесь, но, похоже, это было сосредоточено в направлении Java-XML. Итак, в принципе, xsi: type не выдерживает разборки? –
@MarcusJuniusBrutus - Это определенно делает. Существует ли класс, соответствующий значению атрибута xsi: type? –
Да, есть соответствующий класс. Я просто предполагаю, что если такой класс недоступен в JAXBContext, JAXB, скорее всего, создаст суперкласс, и в этом случае у нас будет какая-то «потеря информации». Но я не пытался воспроизвести эту последнюю гипотетическую ситуацию. –