【问题标题】:JAXB unmarshall to multiple pojo'sJAXB 解组到多个 pojo
【发布时间】:2011-04-25 14:48:16
【问题描述】:

我试图弄清楚是否可以将一个 xml 元素解组为多个 pojo。例如:

对于 xml:

<type>
  <id>1</id>
  <cost>12</cost>
  <height>15</height>
  <width>13</width>
  <depth>77</depth>
</type>

物品类别

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement(name="type")
public class Item {
  private Integer id;
  private Double cost;

  @XmlElement(name="id")
  public Integer getId(){
    return id;
  }

  @XmlElement(name="cost")
  public Double getCost(){
    return cost
  }
}

ItemDimensions 类

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement(name="type")
public class ItemDimensions {
  private Integer height;
  private Integer width;
  private Integer depth;

  @XmlElement(name="height")
  public Integer getHeight(){
    return height;
  }

  @XmlElement(name="width")
  public Integer getWidth(){
    return width;
  }

  @XmlElement(name="depth")
  public Integer getDepth(){
    return depth;
  }
}

我曾尝试使用由 Netbeans 6.9 生成的许多 JAXB 映射和许多测试类来完成类似的事情,但没有成功。有谁知道这是否可以在没有任何中间对象的情况下完成?

【问题讨论】:

  • AFAIK 您必须自己创建 ItemDimensions 对象。例如返回新的 ItemDimensions(高度、宽度、深度)。

标签: java jaxb unmarshalling


【解决方案1】:

您可以使用 EclipseLink JAXB (MOXy) 中的 @XmlPath 扩展来完成这个用例(我是 MOXy 技术负责人):

JAXB 需要一个对象来解组,我们将引入一个类来完成这个角色。此类将具有对应于您希望使用 self XPath 解组注释的两个对象的字段:@XmlPath(".")

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="type")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlPath(".")
    private Item item;

    @XmlPath(".")
    private ItemDimensions itemDimensions;

}

物品尺寸

你通常注释这个类。在您的示例中,您注释了属性,但仅提供了 getter。这将导致 JAXB 认为这些是只写映射。

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class ItemDimensions {

    private Integer height;
    private Integer width;
    private Integer depth;

}

物品

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Item {

    private Integer id;
    private Double cost;

}

演示

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller u = jc.createUnmarshaller();
        Object o = u.unmarshal(new File("input.xml"));

        Marshaller m = jc.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        m.marshal(o, System.out);
    }

}

jaxb.properties

要将 MOXy 用作您的 JAXB 实现,您必须在您的域对象中提供一个名为 jaxb.properties 的文件,其中包含以下条目:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

【讨论】:

  • +1 我不明白“为只写属性注释 getter”部分,您能详细说明或重定向到链接吗?
  • @ekeren - 如果使用了 PROPERTY 访问权限并且没有提供设置器,则 JAXB 实现将无法在解组期间“设置”对象上的值。一种解决方案是提供 setter,另一种是使用 FIELD 访问。
猜你喜欢
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
  • 2015-05-13
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多