【问题标题】:Could JAXB use the base type for a known element with an unknown type?JAXB 可以将基类型用于具有未知类型的已知元素吗?
【发布时间】:2011-09-02 16:20:08
【问题描述】:

给定一个像这样的 XSD:

<!-- ... -->
    <xsd:element name="MyElement" type="ParentType" />
<!-- ... -->
<xsd:complexType name="ParentType">
    <xsd:sequence>
        <!-- ... -->
        </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ChildType1">
    <xsd:complexContent>
        <xsd:extension base="ParentType">
            <xsd:sequence>
                <!-- ... -->
            </xsd:sequence>
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>
<!-- ... -->

当 JAXB2 必须解组包含未知类型元素的 XML 时,是否可以将其配置为回退到基本类型 ParentType,如下例所示:

<!-- ... -->
<MyElement xsi:type="ChildType2">
    <!-- ... -->
</MyElement>
<!-- ... -->

通常,在这种情况下,JAXB 会引发异常,指出 ChildType2 是无法识别的类型。

【问题讨论】:

  • +1 - JAXB 绝对可以在继承层次结构中利用 xsi:type (blog.bdoughan.com/2010/11/…)。您的问题具体是如何处理 xsi:type 与 JAXB 知道的类不对应的情况?
  • 是的,Blaise,我的问题是关于 xsi:type 对应于 JAXB 不知道的类的情况。

标签: java jaxb


【解决方案1】:

这并不完全是您所需要的,但您可以使用 @XmlAnyElement 将未知类型解组为 DOM 元素。

考虑一个Customer 类,其中extras 字段用全能@XmlAnyElement 注释。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
    @XmlElement
    private String name;
    @XmlAnyElement
    private List<Element> extras = new ArrayList<Element>();

    public String getName() {
        return name;
    }

    public List<Element> getExtras() {
      return extras;
    }
}

示例 xml:

<?xml version="1.0" encoding="UTF-8"?>
<customer>
    <name>John Doe</name>
    <salary>1000</salary>
    <age>45</age>
</customer>

SalaryAge 是未知类型,在我们解组时存储在我们的附加列表中:

JAXBContext jc = JAXBContext.newInstance(Customer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Customer customer = (Customer) unmarshaller.unmarshal(reader);
System.out.println(customer.getName());
for (Element el : customer.getExtras()) {
    System.out.println(el.getNodeName() + "->"
               + el.getTextContent());

输出:

John Doe
salary->1000
age->45

【讨论】:

  • +1 - 此外,如果您设置 @XmlAnyElement(lax=true),那么您的 JAXB 实现会将已知类型转换为对象形式:blog.bdoughan.com/2010/08/…
  • 使用@XmlAnyElement 的问题是您必须查看元素列表才能找到所需的内容。例如,在我的例子中,我希望能够使用 JAXB,即使有人用我不知道的新类型更新了 XML 模式,但它是已知类型的扩展。此外,@XmlAnyElement 需要将带注释的元素添加到可能出现未知元素的任何位置,而我不知道这些位置。我虽然可能有一些配置选项或允许这样做的选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多