当前位置: 首页 > 知识库问答 >
问题:

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

郗俊能
2023-03-14

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

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

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

共有1个答案

谯翔
2023-03-14

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

更多信息

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html

更新

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

架构.xsd

在下面的XML架构中,复杂类型< code>canadianAddress扩展了复杂类型< code>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的实例,而不仅仅是0.05地址

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

 类似资料:
  • 我想从JMS中检索一些数据,过滤它们并发送到REST服务器。当我解组这些数据时,我得到一个错误: java.lang.IllegalArgumentException:读取器不能为空 位于com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshalleImpl.unmarshall0(UnmarshallerImpl.java:370)位于com.sun.x

  • 我的代码如下: 我怎样才能让它工作?如果我的xml标记有一些相关元素,如上面的“xmlns”,则JAXB解组器会抛出异常。 这是我第一次这么做,所以我对JAXB、解编等都一无所知。我在苦苦挣扎任何帮助都是好的。 编辑StackTrace:

  • 在使用JAXB时,我希望在使用泛型时从XML元素中删除多余的名称空间/类型。我该怎么做,或者我做错了什么?我想使用泛型,这样我只需要编写一次代码块。 示例代码: 输出:

  • 我正在阅读下面的文件 并将其解析为Book对象 ……。我得到错误: 道:

  • 我已经生成java类使用从一个xsd,其中根元素是类型的。 jaxb生成的根元素是 当我尝试解组与该xsd对应的xml并强制转换JaxbElement时,它会引发一个强制转换异常: 片段:

  • 在不使用getter和setter的情况下,JAXB可以正确地解组所提供的JSON。 null和“null”是完全不同的东西,但是我不想在POJO中包含这个字段,并且我必须忽略这些null值。 编辑