5

JavaオブジェクトをXMLにマーシャリングするためにJAXBを使用しています。私が直面している問題は、Java オブジェクト インスタンスのすべてのメンバー変数を XML にマーシャリングする必要がないことです。たとえば、私の完全な XML ドキュメントは次のようになります。

<Disk>
  <status>attached</status>
  <size>10000000000</size>
  <freeSpace>25600000<freeSpace>
  <id>MI45563PO</id>
</Disk>

ただし、更新の場合、選択したプロパティのみが変更され、変更されたプロパティのみがマーシャリングされた XML の一部である必要があります。同様に、'status' プロパティが 'detached' に変更される可能性があります。その場合、マーシャリングされた XML は次のようになります。

<Disk>
  <status>detached</status>
</Disk>

または、「freeSpace」変更の場合、XML は次のようになります。

<Disk>
  <freeSpace>20000000<freeSpace>
</Disk>

私の質問:変更されていないフィールドを null として定義する (したがって、すべてのプリミティブ型を Integer、Boolean などのラッパー クラス変数として定義する) ことは、目的の結果を得るための唯一の解決策ですか? または、JAXB で選択したフィールドを指定する方法はありますか? 結果の XML でマーシャリングし、残りのフィールドを無視する必要があります。

無視する必要があり、含める必要があるフィールドのセットは、どの時点でも固定されていないことに注意してください。

4

2 に答える 2

2

1つのクラスのビューをいくつか作成する場合は、ビューごとにデコレータクラスを作成する必要があります。ソースコードの例:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;

public class Program {

    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(Disk.class,
                OnlyDiskStatusDecorator.class, OnlyDiskFreeSpaceDecorator.class);
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

        Disk disk = new Disk();
        disk.setStatus("attached");
        disk.setSize(10000000000L);
        disk.setFreeSpace(25600000L);
        disk.setId("MI45563PO");

        m.marshal(disk, System.out);
        m.marshal(new OnlyDiskStatusDecorator(disk), System.out);
        m.marshal(new OnlyDiskFreeSpaceDecorator(disk), System.out);
    }

}

@XmlRootElement
class Disk {
    private String status;
    private long size;
    private long freeSpace;
    private String id;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public long getFreeSpace() {
        return freeSpace;
    }

    public void setFreeSpace(long freeSpace) {
        this.freeSpace = freeSpace;
    }

    public String getId() {
        return id;
    }

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

    @Override
    public String toString() {
        return "Disk [status=" + status + ", size=" + size + ", freeSpace="
                + freeSpace + ", id=" + id + "]";
    }
}

@XmlRootElement(name = "Disk")
class OnlyDiskStatusDecorator {
    private Disk disk;

    public OnlyDiskStatusDecorator() {
    }

    public OnlyDiskStatusDecorator(Disk disk) {
        this.disk = disk;
    }

    public String getStatus() {
        return disk.getStatus();
    }

    public void setStatus(String status) {
    }
}

@XmlRootElement(name = "Disk")
class OnlyDiskFreeSpaceDecorator {
    private Disk disk;

    public OnlyDiskFreeSpaceDecorator() {
    }

    public OnlyDiskFreeSpaceDecorator(Disk disk) {
        this.disk = disk;
    }

    public long getFreeSpace() {
        return disk.getFreeSpace();
    }

    public void setFreeSpace(long freeSpace) {
    }
}

上記の例の印刷:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<disk>
    <freeSpace>25600000</freeSpace>
    <id>MI45563PO</id>
    <size>10000000000</size>
    <status>attached</status>
</disk>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Disk>
    <status>attached</status>
</Disk>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Disk>
    <freeSpace>25600000</freeSpace>
</Disk>

クラスの2つのビューに対して2つのデコレータを作成しました。ステータス更新用の最初のデコレータとfreeSpace値の更新用の2番目のデコレータ。特定のシリアル化のためにXmlAdapterの実装を作成することもできますが、もう少し複雑だと思います。

于 2012-11-26T21:02:25.613 に答える
0

XML でXSL 変換を使用し、次に JAXB を使用することについて考えたことはありますか?

私も似たような状況にあり、約 3000 の JAXB DTO がありました。それらを扱いやすい数、28に減らしました。

w3schoolsのチュートリアルをご覧ください。

于 2012-11-27T08:19:15.317 に答える