JAXB:如何在解组时读取xsi:type值

时间:2013-06-03 18:42:53

标签: java xml jaxb xsd

我在 XSD / XML 中使用 JAXB 到Java方向。我的 XSD 包含派生类型, XML 我必须解组包含 xsi:type 属性。查看代码 JAXB (默认的Sun实现)已经生成(用于解组)似乎没有方法来获取这些属性。

是不是因为我总是可以在unmarshalled Java对象上做getClass()并找到实际的类?

但是,根据我提供给JAXBContext.newInstance某些基类的包或类,可能会被实例化吗? (一个是类的超类,对应于 xsi:type 属性的实际值)。在这种情况下,可能需要读取XML实例中出现的实际属性的值。

1 个答案:

答案 0 :(得分:3)

JAXB (JSR-222)实施将为您处理一切。 JAXB认为每个类对应一个复杂类型。它有一个算法来确定类型名称,但您可以使用@XmlType注释覆盖它。如果某个元素包含xsi:type属性,则该元素是非编组的,那么JAXB将查看是否存在与该类型相关联的类。如果有,它将实例化该类型的类,如果不是,它将基于通过注释提供的映射元数据实例化与该元素对应的类型。

了解更多信息


<强>更新

以下是一个可能有用的示例:

<强> 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>

<强>演示

在下面的演示代码中,XML将转换为从上面的XML模式生成的JAXB模型,然后转换回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>