7

JAXBは書き込み内容を読み取れないようです。次のコードを検討してください。

interface IFoo {
    void jump();
}

@XmlRootElement
class Bar implements IFoo {
    @XmlElement
    public String y;

    public Bar() {
        y = "";
    }

    public Bar(String y) {
        this.y = y;
    }

    @Override
    public void jump() {
        System.out.println(y);
    }
}

@XmlRootElement
class Baz implements IFoo {
    @XmlElement
    public int x;

    public Baz() {
        x = 0;
    }

    public Baz(int x) {
        this.x = x;
    }

    @Override
    public void jump() {
        System.out.println(x);
    }
}

@XmlRootElement
public class Holder {
    private List<IFoo> things;

    public Holder() {
        things = new ArrayList<>();
    }

    @XmlElementWrapper
    @XmlAnyElement
    public List<IFoo> getThings() {
        return things;
    }

    public void addThing(IFoo thing) {
        things.add(thing);
    }
}

// ...

try {
    JAXBContext context = JAXBContext.newInstance(Holder.class, Bar.class, Baz.class);

    Holder holder = new Holder();
    holder.addThing(new Bar("1"));
    holder.addThing(new Baz(2));
    holder.addThing(new Baz(3));

    for (IFoo thing : holder.getThings()) {
        thing.jump();
    }

    StringWriter s = new StringWriter();
    context.createMarshaller().marshal(holder, s);

    String data = s.toString();

    System.out.println(data);

    StringReader t = new StringReader(data);
    Holder holder2 = (Holder)context.createUnmarshaller().unmarshal(t);

    for (IFoo thing : holder2.getThings()) {
        thing.jump();
    }
}
catch (Exception e) {
    System.err.println(e.getMessage());
}

もちろん、これは単純化された例です。重要なのは、非常に異なる方法で実装された2つのクラス、BarとBazを1つのコレクションに格納する必要があるということです。まあ、私はそれらが非常に似たパブリックインターフェイスを持っていることを観察したので、私はインターフェイスIFooを作成し、それを実装するために2つにしました。ここで、このコレクションをXMLとの間で保存およびロードするためのツールが必要です。残念ながら、このコードは完全には機能しません。コレクションは保存されますが、ロードできません。意図した出力は

1
2
3
some xml
1
2
3

しかし残念ながら、実際の出力は

1
2
3
some xml
com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to testapplication1.IFoo

どうやら、私は別の方法で注釈を使用する必要がありますか?または、JAXBをあきらめて、何か他のものを探すために?私は、(デ)マーシャリングしたくないすべてのクラスに対して「XMLNodetoXML()」メソッドを記述できますが、...

4

1 に答える 1

10

次のことを試してください@XmlAnyElement(lax=true)。このフラグは、JAXB(JSR-222)実装に、要素と注釈laxに基づいて要素をドメインオブジェクトに一致させるように指示します。これがないと、コンテンツはDOMノードとして扱われます。@XmlRootElement@XmlElementDecl

@XmlRootElement
public class Holder {
    private List<IFoo> things;

    public Holder() {
        things = new ArrayList<>();
    }

    @XmlElementWrapper
    @XmlAnyElement(lax=true)
    public List<IFoo> getThings() {
        return things;
    }

    public void addThing(IFoo thing) {
        things.add(thing);
    }
}

詳細については

于 2012-06-20T20:53:15.083 に答える