2012-12-20 37 views
11

我如何指示JAXB處理這個問題?如何使用JAXB解組重複的嵌套類?

XML

<root> 
<parent> 
    <child id="1" name="foo" /> 
</parent> 
<parent> 
    <child id="3" name="foo2" /> 
</parent> 
<parent> 
    <child id="4" name="bar2" /> 
</parent> 
<parent> 
    <child id="2" name="bar" /> 
</parent> 
</root> 

Root.java

@XmlRootElement 
public class Root { 
    @XmlElement(name="parent/child") 
    List<Child> allChildren; 
} 

這不工作... allChildren是空的。

回答

13

你可以改變你的模型,並做到以下幾點:

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 
    @XmlElement(name="parent") 
    List<Parent> allParents; 
} 

家長

@XmlAccessorType(XmlAccessType.FIELD) 
public class Parent { 
    @XmlElement(name="child") 
    List<Child> allChildren; 
} 

UPDATE

是否有可能避免父類?

有幾種不同的方式來實現:

選項1 - 使用XmlAdapter

你可以使用一個XmlAdapter在Parent類幾乎添加任何JAXB實現。

ChildAdapter

import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class ChildAdapter extends XmlAdapter<ChildAdapter.Parent, Child> { 

    public static class Parent { 
     public Child child; 
    } 

    @Override 
    public Parent marshal(Child v) throws Exception { 
     Parent parent = new Parent(); 
     parent.child = v; 
     return parent; 
    } 

    @Override 
    public Child unmarshal(Parent v) throws Exception { 
     return v.child; 
    } 

} 

@XmlJavaTypeAdapter註釋用於引用XmlAdapter

import java.util.List; 
import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    @XmlElement(name="parent") 
    @XmlJavaTypeAdapter(ChildAdapter.class) 
    List<Child> allChildren; 

} 

兒童

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Child { 

    @XmlAttribute 
    int id; 

    @XmlAttribute 
    String name; 

} 

選項#2 - 使用的EclipseLink JAXB(莫西)

如果您正在使用EclipseLink JAXB (MOXy)爲您JAXB (JSR-222)實現,那麼你可以做以下(注:我是MOXy的領導):

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    @XmlElement(name="parent") 
    List<Child> allChildren; 

} 

兒童

莫西的@XmlPath註釋工作幾乎你想使用@XmlElement標註在您的文章的方式。

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlPath; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Child { 

    @XmlPath("child/@id") 
    int id; 

    @XmlPath("child/@name") 
    String name; 

} 

更多信息

+0

是否有可能避免父類? – Stephan

+4

+1當我獨立地提出與該領域公認的專家完全相同的解決方案時,總是令人放心:-) –

+1

@IanRoberts - 我+也爲您解答了答案:)。 –

1

你可以嘗試使用XmlElementWrapper註解,但是我不知道應該如何與多個封裝節點的工作:

@XmlRootElement 
public class Root { 
    @XmlElementWrapper(name="parent") 
    @XmlElement(name="child") 
    List<Child> allChildren; 
} 
+0

我只得到一個孩子,而不是所有的孩子。 – Stephan

0

試試這個

@XmlRootElement 
class Root { 
    List<Child> allChildren = new ArrayList<Child>(); 

    private static class Parent { 
     @XmlElement 
     Child child; 
    } 

    @XmlElement 
    public void setParent(Parent p) { 
     allChildren.add(p.child); 
    } 
} 
+0

是的,他這樣做,但這裏的父母只是一個伎倆,只是一個私人課程。最重要的是,我們有名單沒有名單

2

您必須創建表示<parent>元素的類,如

@XmlAccessorType(XmlAccessType.FIELD) 
public class Parent { 
    @XmlElement(name="child") 
    Child child; 
} 

然後,您可以創建一個類型的適配器

public class ParentToChildAdapter extends XmlAdapter<Parent, Child> { 
    public Parent marshal(Child c) { 
    Parent p = new Parent(); 
    p.child = child; 
    return p; 
    } 

    public Child unmarshal(Parent p) { 
    return p.child; 
    } 
} 

和使用上的根類

@XmlRootElement 
public class Root { 
    @XmlElement(name="parent") 
    @XmlJavaTypeAdapter(ParentToChildAdapter.class) 
    List<Child> allChildren; 
}