7

JAXB を使用してレガシー システムから XML ドキュメントを非整列化しようとしています。私は次のようなxml構造を持っています:

<response>
    <id>000000</id>
    <results>
        <result>
<!-- Request specific xml content -->
            <year>2003</year>
            <title>Lorem Ipsum</title>
            <items>
                <item>I1</item>
                <item>I2</item>
            </items>
        </result>
        <result>
            <year>2007</year>
            <title>Dolor sit amet</title>
            <items>
                <item>K1</item>
                <item>K2</item>
            </items>
        </result>
    </results>
</response>

tagで指定した部分内の<result>タグは、私のリクエストに応じて変更します。コンテンツが変更される可能性があるため、結果項目にジェネリックを使用することにし、次のようにアノテーションを使用して Java Bean を準備しました。

// imports here
@XmlRootElement(name="response")
@XmlAccessorType(XmlAccessType.FIELD)
public class XResponse<T>{
    private String id;

    @XmlElementWrapper(name="results")
    @XmlElement(name="result")
    private List<T> results;

// setters and getters
}

...

@XmlRootElement(name="result")
@XmlAccessorType(XmlAccessType.FIELD)
public class X1Result{
    private String year;
    private String title;
    @XmlElementWrapper(name="items")
    @XmlElement(name="item")
    private List<String> items;

// setters and getters
}
...

以下のコードを使用して、xml ドキュメントをアンマーシャリングしてみました。

JAXBContext context = JAXBContext.newInstance(XResponse.class, X1Result.class);
Unmarshaller um = context.createUnmarshaller();
XResponse<X1Result> response = (XResponse<X1Result>) um.unmarshal( xmlContent );

List<X1Result> results = unmarshal.getResults();
for (X1Result object : results) {
    System.out.println(object.getClass());
}

X1Resultアンマーシャリング中に、リスト項目をクラスにキャストできないという問題があります。代わりに を使用しますorg.apache.xerces.dom.ElementNSImpl

JAXB Unmarshaller でクラスを使用するにはどうすればよいX1Resultですか?

前もって感謝します

4

1 に答える 1

2

ジェネリックの代わりに継承を使用する必要があると思います。次のような XML があるとします。

<?xml version="1.0" encoding="UTF-8"?>
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <id>000000</id>
    <results>
        <result xsi:type="X1Result">
            <year>2003</year>
            <title>Lorem Ipsum</title>
            <items>
                <item>I1</item>
                <item>I2</item>
            </items>
        </result>
        <result xsi:type="X1Result">
            <year>2007</year>
            <title>Dolor sit amet</title>
            <items>
                <item>K1</item>
                <item>K2</item>
            </items>
        </result>
    </results>
</response>

<result>エントリを動的にバインドできます。トップレベルのタイプがあります:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "XResult")
@XmlSeeAlso({
    X1Result.class
})public abstract class XResult {

}

そして、クラスを実装しています:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "X1Result")
public class X1Result extends XResult {
    @XmlElement(name = "year")
    private String year;

    @XmlElement(name = "title")
    private String title;

    @XmlElementWrapper(name = "items")
    @XmlElement(name = "item")
    private List<String> items;
    ...
}

XResponse クラスで最上位の型を使用します。

@XmlRootElement(name = "response")
@XmlAccessorType(XmlAccessType.FIELD)
public class XResponse {
    @XmlElement(name = "id")
    private String id;

    @XmlElementWrapper(name = "results")
    @XmlElement(name = "result")
    private List<XResult> results;
    ...
}

また、最上位の型を使用して非整列化できます。

context = JAXBContext.newInstance(XResponse.class, XResult.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
XResponse response = (XResponse) unmarshaller.unmarshal(new File("testfile.xml"));

List<XResult> results = response.getResults();
for (XResult object : results) {
    System.out.println(object.getClass());
}
于 2012-10-05T17:55:25.830 に答える