11

これを処理するように 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>

ルート.java

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

これは機能しません... allChildren は空です。

4

4 に答える 4

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;
}

アップデート

親クラスを避けることは可能ですか?

これを実現するには、いくつかの方法があります。

オプション #1 - XmlAdapter を使用した任意の JAXB 実装

XmlAdapter を使用して、Parentクラスに仮想的に追加できます。

子アダプタ

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 (MOXy) の使用

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;

}

MOXy の注釈は、投稿で注釈@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;

}

詳細については

于 2012-12-20T15:47:54.840 に答える
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;
}
于 2012-12-20T16:14:57.153 に答える
1

アノテーションを使用することもできますがXmlElementWrapper、複数のラッパー ノードでどのように機能するかはわかりません。

@XmlRootElement
public class Root {
   @XmlElementWrapper(name="parent")
   @XmlElement(name="child")
   List<Child> allChildren;
}
于 2012-12-20T15:46:05.567 に答える
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);
    }
}
于 2012-12-20T16:00:48.047 に答える