4

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

是因为我总是可以getClass()对未编组的 Java 对象执行 a 并找到实际的类吗?

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

4

1 回答 1

3

JAXB (JSR-222)实现将为您处理一切。JAXB 认为每个类对应一个复杂类型。它有一个计算类型名称的算法,但您可以使用@XmlType注释覆盖它。当一个元素被解组时,如果它包含一个xsi:type属性,那么 JAXB 将查看是否有一个与该类型关联的类。如果存在,它将实例化该类型的类,如果没有,它将根据通过注释提供的映射元数据实例化与该元素对应的类型。

了解更多信息


更新

下面是一个可能有帮助的例子:

架构.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);
    }

}

输入.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>
于 2013-06-03T18:58:23.573 回答