JAXB基于兄弟元素的解组

时间:2010-02-23 09:04:34

标签: java jaxb unmarshalling

我有以下xml片段(在我无法控制的范围内):

<item>
  <name>Name</name>
  <category>1</category>
  <subcategory>2</subcategory>
</item>

我希望将<subcategory>解组为一个看起来像这样的类:

public class SubCategory {
  private Category parent;
  private int code;
  private String name;

  public SubCategory(int code, Category parent){
    this.code = code;
    this.parent = parent;
    this.name = lookupName(code);
  }

  // Getters, setters and lookupName(int) here
}

换句话说,<category>标记产生的对象应该传递给<subcategory>元素产生的对象。

我该怎么做?这甚至可能吗?我知道XmlAdapter,但我认为没办法抓住父母。

如果它可以在构造函数中完成,我更喜欢它,所以实例永远不会处于无效状态,但我会选择不同的解决方案,只要我不必手动设置每个SubCategory的父级。

3 个答案:

答案 0 :(得分:2)

JAXB不会为您执行此操作。 XmlAdapter不适合此问题。当类结构与XML结构明显不同时,您需要在JAXB绑定(使用XSLT)之前或在JAXB绑定之后(使用Java)执行其他级别的转换。

后一种选择更容易。您将需要一个表示XML结构的类,以及一个转换路由,它将实例绑定到您所需结构的实例。

答案 1 :(得分:2)

如果您调整XMLAdapter而不是Item,则可以使用SubCategory执行此操作。

ItemAdapter.java:

public class ItemAdapter extends XmlAdapter<ItemProxy, Item>
{
    @Override
    public ItemProxy marshal( Item v ) throws Exception
    {
        ItemProxy proxy = new ItemProxy();

        proxy.setCategory( v.getCategory().getCode() );
        proxy.setSubcategory( v.getSubCategory().getCode() );
        proxy.setName( v.getName() );

        return proxy;
    }

    @Override
    public Item unmarshal( ItemProxy v ) throws Exception
    {
        Item item = new Item();

        Category category = new Category( v.getCategory() );
        SubCategory subCategory = new SubCategory( v.getSubcategory(), category );

        item.setName( v.getName() );
        item.setCategory( category );
        item.setSubCategory( subCategory );

        return item;
    }
}

ItemProxy.java:

@XmlRootElement( name = "item" )
public class ItemProxy
{
    private String name;
    private int category;
    private int subcategory;

    @XmlElement
    public String getName()
    {
        return name;
    }

    @XmlElement
    public int getCategory()
    {
        return category;
    }

    @XmlElement
    public int getSubcategory()
    {
        return subcategory;
    }

    public void setName( String name )
    {
        this.name = name;
    }

    public void setCategory( int category )
    {
        this.category = category;
    }

    public void setSubcategory( int subcategory )
    {
        this.subcategory = subcategory;
    }
}

答案 2 :(得分:0)

我能想到如何做到这一点的一种方法是编写一些XSLT,它可以在JAXB中更容易地映射XML。虽然这可能会奏效,但这是我宁愿避免的额外步骤。