我在 XSD / XML 中使用 JAXB 到Java方向。我的 XSD 包含派生类型, XML 我必须解组包含 xsi:type 属性。查看代码 JAXB (默认的Sun实现)已经生成(用于解组)似乎没有方法来获取这些属性。
是不是因为我总是可以在unmarshalled Java对象上做getClass()
并找到实际的类?
但是,根据我提供给JAXBContext.newInstance
某些基类的包或类,可能会被实例化吗? (一个是类的超类,对应于 xsi:type 属性的实际值)。在这种情况下,可能需要读取XML实例中出现的实际属性的值。
答案 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>