1

オブジェクトをXMLとして保存し、そのXMLを読み取り、別のXMLに保存します。2つのXMLファイルは異なります。

最初のXML(私の予想):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multiIDTest>
    <containerList>
        <container id="1">
            <elem id="1"/>
        </container>
        <container container="1" id="2"/>
        <container container="2" id="3"/>
    </containerList>
</multiIDTest>

2番目のXML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multiIDTest>
    <containerList>
        <container id="1">
            <elem id="1"/>
        </container>
        <container id="2"/>
        <container container="2" id="3"/>
    </containerList>
</multiIDTest>

サブ要素IDを変更した場合:

最初のXML(私の予想):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multiIDTest>
    <containerList>
        <container id="1">
            <elem id="2"/>
        </container>
        <container container="1" id="2"/>
        <container container="2" id="3"/>
    </containerList>
</multiIDTest>

2番目のXML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multiIDTest>
    <containerList>
        <container id="1">
            <elem id="2"/>
        </container>
        <container container="1" id="2"/>
        <container container="2" id="3"/>
    </containerList>
</multiIDTest>

おかしいです。誰が私に理由を教えてくれますか?

サンプルコード:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package xml;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class MultiIDTest {

    static public class Element {
        private String id;

        @XmlID
        @XmlAttribute(required=true)
        public String getId() {
            return id;
        }

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

    static public class Container {
        private String id;

        @XmlID
        @XmlAttribute(required=true)
        public String getId() {
            return id;
        }

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

        private Container container;

        @XmlIDREF
        @XmlAttribute(required=true)
        public Container getContainer() {
            return container;
        }

        public void setContainer(Container e) {
            this.container = e;
        }

        private Element elem;

        public Element getElem() {
            return elem;
        }

        public void setElem(Element e) {
            this.elem = e;
        }
    }

    static public class XmlSerialization {
        public static Object read(String filepath, Class... classesToBeBound) {
            try {
                return JAXBContext.newInstance(classesToBeBound).createUnmarshaller().unmarshal(new File(filepath));
            } catch (JAXBException ex) {}
            return null;
        }

        public static void write(String filePath, Object entity, Class... classesToBeBound) {
            try {
                Marshaller m = JAXBContext.newInstance(classesToBeBound).createMarshaller();
                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                m.marshal(entity, new File(filePath));
            } catch (JAXBException ex) {}
        }

    }
    List<Container> containerList = new ArrayList<>();
    @XmlElementWrapper(name="containerList")
    @XmlElement(name="container")
    public List<Container> getContainerList() {
        return (containerList != null)?containerList:(containerList = new ArrayList<>());
    }

    public void setContainerList(List<Container> containerList) {
        this.containerList = containerList;
    }
    public void initialize() {
        Container container = new Container();
        container.setId("1");
        Element elem = new Element();
        elem.setId("2"); // if I use elem.setId("1"), problem occurs.
        container.setElem(elem);

        containerList.add(container);
        Container container2 = new Container();
        container2.setId("2");
        container2.setContainer(container);
        containerList.add(container2);

        Container container3 = new Container();
        container3.setId("3");
        container3.setContainer(container2);
        containerList.add(container3);
    }
    public void write(String filePath, Object obj) {
        XmlSerialization.write(filePath, obj, MultiIDTest.class, Container.class, Element.class);
    }
    public Object read(String filePath) {
        return XmlSerialization.read(filePath, MultiIDTest.class, Container.class, Element.class);
    }

    public static void main(String[] args) {
        MultiIDTest test = new MultiIDTest();
        String filePath = "c:\\tmp.xml";
        test.initialize();
        test.write(filePath, test);
        MultiIDTest test2 = (MultiIDTest)test.read(filePath);
        test.write("c:\\tmp2.xml", test2);
    }
}
4

1 に答える 1

1

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

JAXB RI の問題

JAXB 2.2 (JSR-222) はこのユースケースを処理できますが、使用している特定の JAXB 実装にバグがあり、動作を妨げている場合があります。Mac 用の JDK 1.7.0 に含まれる JAXB 2.2 実装を使用して発生している問題を確認できました。この問題についてバグを開くことをお勧めします。

その他の JAXB 実装

サンプル コードを EclipseLink JAXB (MOXy) で試してみましたが、期待どおりに動作します。私は MOXy のリーダーです。次の場所からダウンロードできます。

詳細については

于 2012-10-10T13:13:53.420 に答える