JAXB: how to read xsi: type value when unmarshalling

I am using JAXB in XSD / XML in the direction of Java. My XSD contains derived types and XML . I need unmarshall to contain xsi: type attributes. A look at the JAXB code (Sun's default implementation) generated (for unmarshalling), it seems there are no methods to get these attributes.

Is it because I can always do getClass() on an unmarshalled Java object and find the actual class?

However, is it not so that, depending on the packages or classes that I provide JAXBContext.newInstance , an instance of some base class can be created? (one that is the superclass of the class corresponding to the actual value of the xsi: type attribute). In this case, it may be necessary to read the value of the actual attribute as it appears in the XML instance.

+4
source share
1 answer

The JAXB implementation (JSR-222) will take care of everything for you. JAXB believes that each class corresponds to a complex type. It has an algorithm to determine the type name, but you can override it using the @XmlType annotation. When an element is unarmalized, if it contains the xsi:type attribute, then JAXB will look to see if there is a class associated with this type. If it does, it will create an instance of the class of this type, if it does not create an instance of the type corresponding to this element, based on the display metadata provided through annotations.

Additional Information


UPDATE

The following is an example that might help:

schema.xsd

In the XML schema below, the complex type canadianAddress extends 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

In the demo code below, the XML will be converted to a JAXB model generated from the XML schema above, and then converted back to 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 / output

The following is XML. The address element is xsi:type qualified to indicate that it contains a canadianAddress instance, not just an 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> 
+3
source

Source: https://habr.com/ru/post/1484266/


All Articles