3

私は、単一の Java クラスにマッピングしている無意味なラッパーがたくさんある深い XML 構造を持っています。単純なデータ型を @XmlPath でマッピングするのは簡単なことですが、実際に独自のクラスを必要とする型に関しては、特にそれらの型をリストに入れる必要がある場合は特に、その方法がよくわかりません。

element以下の例のすべての型を自分のElementクラスにマップするのに問題があります。elementsラッパーは を使用してマップされたリソースに存在するため、 を@XmlPath使用できません@XmlElementWrapper。それ以外の場合は通常これを行う方法です。

XML 構造の例

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <s:resource>
        <s:information>
            <s:date>2013-07-04</s:date>
            <s:name>This example does not work</s:name>
        </s:information>
        <s:elements>
            <s:refobj>
                <s:id>1</s:id>
                <s:source>First Source</s:source>
            </s:refobj>
            <s:refobj>
                <s:id>2</s:id>
                <s:source>Second Source</s:source>
            </s:refobj>
            <s:refobj>
                <s:id>5</s:id>
                <s:source>Fifth Source</s:source>
            </s:refobj>
        </s:elements>
    </s:resource>
</s:root>

ルート.java

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlPath("resource/information/date/text()")
    private String date;

    @XmlPath("s:resource/s:information/s:name/text()")
    private String name;

    @XmlPath("resource/elements/refobj")
    private List<RefObj> refObjs;

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getName() {
        return name;
    }

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

}

RefObj.java

@XmlRootElement(name = "refobj")
@XmlAccessorType(XmlAccessType.FIELD)
public class RefObj {

    @XmlElement(name = "id")
    private int id;

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

}

マーシャラー/アンマーシャラー

public static void main(String[] args) {
    String xml = getXML();

    Root root = null;
    try {
        JAXBContext context = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = context.createUnmarshaller();

        StringReader stringReader = new StringReader(xml);

        root = (Root) unmarshaller.unmarshal(stringReader);
    } catch (Exception ex) {
        System.err.println("Failed to unmarshal XML!");
    }

    try {
        JAXBContext context = JAXBContext.newInstance(Root.class);
        Marshaller marshaller = context.createMarshaller();

        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.eu/test ResourceSchema.xsd");

        StringWriter stringWriter = new StringWriter();
        marshaller.marshal(root, stringWriter);

        System.out.println(new String(stringWriter.toString().getBytes(Charset.forName("UTF-8"))));
    } catch (Exception ex) {
        System.err.println("Failed to marshal object!");
    }

}

パッケージ情報.java

@XmlSchema(
        namespace = "http://www.example.eu/test",
        attributeFormDefault = XmlNsForm.QUALIFIED,
        elementFormDefault = XmlNsForm.QUALIFIED,
        xmlns = {
    @XmlNs(
            prefix = "s",
            namespaceURI = "http://www.example.eu/test")
},
        location = "http://www.example.eu/test ResourceSchema.xsd")
package se.example.mavenproject1;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

アプリケーションを実行できますが、XML コンテンツをアンマーシャリング/マーシャリングするときに要素がマップされず、代わりに情報だけを含む XML 表現が取得されます。

アップデート

前の例を投稿した後、実際に意図したとおりに機能することに気付き、さらに混乱しました。私は実稼働コードで (以前の) 動作する例を複製しようとしましたが、成功しませんでしたが、実際に問題をサンプル コードに導入することができました。問題が発生するために名前空間を追加する必要があったため、命名規則と X(ml)Path に関係があると推測しています。

package-info.javaまた、これらのオブジェクトを操作するときに使用しているマーシャラー/アンマーシャラーも追加しました。jaxb.properties には刺激的なものが何も含まれていないため、省略しました。

4

2 に答える 2

2

そのため、パスを複雑なオブジェクトにマッピングする場合は で名前空間を指定する必要があるように見えますが、や@XmlPathなどの単純なオブジェクトにパスをマッピングする場合はスキップできます。Stringinteger

元の、間違った、コード

@XmlPath("resource/elements/refobj")
private List<RefObj> refObjs;

更新された作業コード

@XmlPath("s:resource/s:elements/s:refobj")
private List<RefObj> refObjs;

@XmlPath名前空間プレフィックスをすべてのオブジェクトに追加すると、期待どおりにマップされます。誰かがこれを確認し、おそらくその理由を説明できる場合は、この動作の理由を知りたい.

于 2013-07-04T12:23:15.217 に答える