1

私は2つのXmlファイルを持っています。

<A>
    <B>xxx</B>
</A>

もう一つは

<A>
<B>
<C>xxx</C>
</B>
</A>

B要素については、フィールドで を作成しましValueObjectString。また、要素XmlAdapter<Object, ValueObject>booleanプロパティを使用して を作成しました。アンマーシャリングするときにできるので、から変換しようとすると、 から変換しようとするとわかります。BsetAdapter(BXmlAdapter.class, new BxmlAdaper(boolean))BxmlAdaperStringValueObject

要素に最初の xml と2 番目のxmlBの属性がある場合。それはうまくいきます。それらすべてを 1 つで非整列化できます 。しかし、なしで、アンマーシャルメソッドのインスタンスを取得しました。どうすればこのケースを解決できますか。xsi:type="prefix:ValueObject"xsi:type="xs:string"xmlValueObjectxsi:typeorg.apache.xerces.dom.ElementNSImplXmlAdapter

これら 2 つのファイル用に 2 つのスキーマ ファイルもあります。そのため、 file を使用して JAXB に要素の型を伝えるxmlことができるのではないかと考えました。しかし、JAXBはスキーマファイルを使用してチェックしているようです。私は何かが恋しいですか?schemaB

これがクラスAのサンプルコードです

package example.dto;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import example.adapter.BXmlAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A {

    @XmlJavaTypeAdapter(BXmlAdapter.class)
    private B b;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

クラスB

    package example.dto;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="B")
public class B {

    private String test;

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

}

パッケージ情報

@javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, namespace = "http://test/test", xmlns = @javax.xml.bind.annotation.XmlNs(prefix = "test", namespaceURI = "http://test/test"))
package example.dto;

jaxb.in​​dex

A
B

BXmlAdapter.java

    package example.adapter;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import example.dto.B;

public class BXmlAdapter extends XmlAdapter<Object, B> {

    private final boolean flg;

    public BXmlAdapter() {
        this.flg = false;
    }

    public BXmlAdapter(boolean flg) {
        this.flg = flg;
    }

    @Override
    public Object marshal(B v) throws Exception {
        if (flg) {
            return v.getTest();
        } else {
            return v;
        }
    }

    @Override
    public B unmarshal(Object v) throws Exception {
        if (flg) {
            B b = new B();
            b.setTest((String) v);
            return b;
        } else {
            return (B) v;
        }
    }
}

A1.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
    <test:b xsi:type="test:B" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <test:test>xxxx</test:test>
    </test:b>
</test:a>

A2.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
    <test:b xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">xxxx2</test:b>
</test:a>

Xml2JavaObject.java

   import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.xml.sax.SAXException;

import example.adapter.BXmlAdapter;
import example.dto.A;

public class Xml2JavaObject {

    public static void main(String[] args) throws ClassNotFoundException,
            SAXException {
        try {
            File file = new File("D:\\jaxb\\A1.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

            jaxbUnmarshaller.setAdapter(BXmlAdapter.class,
                    new BXmlAdapter(false));
            A a = (A) jaxbUnmarshaller.unmarshal(file);
            System.out.println(a.getB().getTest());
        } catch (JAXBException e) {
            e.printStackTrace();
        }

        try {
            File file = new File("D:\\jaxb\\A2.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

            jaxbUnmarshaller.setAdapter(BXmlAdapter.class,
                    new BXmlAdapter(true));
            A a = (A) jaxbUnmarshaller.unmarshal(file);
            System.out.println(a.getB().getTest());
        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }

}

上記のコードは問題なく動作しますが、xml ファイルに xsi:type がない場合。それは動作しません。BXmlAdapter の unmarshal メソッドのパラメータは ElementNSImpl のインスタンスです....

そして私の質問は

  1. ElementNSImpl インスタンスの処理方法

  2. xml ファイルに xsi:type がない場合、JAXB は 1 つの ValueObject を使用して異なる xml ファイルを処理できますか?

  3. xsi:type もスキーマ ファイルにあります。JAXBはスキーマファイルを使用してタイプを決定できますか? JAXBは検証にスキーマファイルを使用しているようです。

ありがとう

4

1 に答える 1

0

@XmlMixed And XmlAdapter を使用して、これを解決する少し醜い方法を見つけました。これがコードクラスAです

package example.dto;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import example.adapter.BXmlAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A {

    @XmlJavaTypeAdapter(value=BXmlAdapter.class)
    private B b;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

}

クラスB

package example.dto;

public class B {

    private String test;

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

}

クラスXmlB

package example.dto;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "B")
public class XmlB {

    @XmlMixed
    private List<Object> tempElement;

    private String test;

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

    public List<Object> getTempElement() {
        return tempElement;
    }

    public void setTempElement(List<Object> tempElement) {
        this.tempElement = tempElement;
    }

}

パッケージ情報.java

@javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, namespace = "http://test/test", xmlns = @javax.xml.bind.annotation.XmlNs(prefix = "test", namespaceURI = "http://test/test"))
package example.dto;

jaxb.in​​dex

A
XmlB

A1.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
    <test:b>
        <test:test>xxxx</test:test>
    </test:b>
</test:a>

A2.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
    <test:b>xxxx2</test:b>
</test:a>

BXmlAdapter.java

package example.adapter;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import example.dto.B;
import example.dto.XmlB;

public class BXmlAdapter extends XmlAdapter<XmlB, B> {

    private final boolean flg;

    public BXmlAdapter() {
        this.flg = false;
    }

    public BXmlAdapter(boolean flg) {
        this.flg = flg;
    }

    @Override
    public XmlB marshal(B v) throws Exception {

        XmlB xmlb = new XmlB();

        if (flg) {
            List<Object> tempElement = new ArrayList<>();
            tempElement.add(v.getTest());
            xmlb.setTempElement(tempElement);
        } else {
            xmlb.setTest(v.getTest());
        }

        return xmlb;
    }

    @Override
    public B unmarshal(XmlB v) throws Exception {
        B b = new B();
        if (flg) {
            if (v.getTempElement() != null && v.getTempElement().size() == 1) {
                b.setTest((String) v.getTempElement().get(0));
            }
        } else {
            b.setTest(v.getTest());
        }

        return b;
    }

}

JavaObject2Xml.java

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import example.adapter.BXmlAdapter;
import example.dto.A;
import example.dto.B;

public class JavaObject2Xml {

    public static void main(String[] args) throws ClassNotFoundException {

        A a1 = new A();
        A a2 = new A();
        B b1 = new B();
        B b2 = new B();
        b1.setTest("xxxx");
        b2.setTest("xxxx2");

        a1.setB(b1);
        a2.setB(b2);

        try {

            File fileA1 = new File("D:\\jaxb\\A1.xml");

            JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.setAdapter(BXmlAdapter.class, new BXmlAdapter(false));
            jaxbMarshaller.marshal(a1, fileA1);

        } catch (JAXBException e) {
            e.printStackTrace();
        }

        try {

            File fileA2 = new File("D:\\jaxb\\A2.xml");

            JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.setAdapter(BXmlAdapter.class, new BXmlAdapter(true));
            jaxbMarshaller.marshal(a2, fileA2);

        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }

}

Xml2JavaObject.java

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.xml.sax.SAXException;

import example.adapter.BXmlAdapter;
import example.dto.A;

public class Xml2JavaObject {

    public static void main(String[] args) throws ClassNotFoundException,
            SAXException {
        try {
            File file = new File("D:\\jaxb\\A1.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            jaxbUnmarshaller.setAdapter(BXmlAdapter.class, new BXmlAdapter(false));
            A a = (A) jaxbUnmarshaller.unmarshal(file);
            System.out.println(a.getB().getTest());
        } catch (JAXBException e) {
            e.printStackTrace();
        }

        try {
            File file = new File("D:\\jaxb\\A2.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            jaxbUnmarshaller.setAdapter(BXmlAdapter.class,new BXmlAdapter(true));
            A a = (A) jaxbUnmarshaller.unmarshal(file);
            System.out.println(a.getB().getTest());
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

}

上記のコードは、クラスの 1 つのグループを使用して 2 つ以上の xml ファイルを処理するのに役立ちます

于 2013-05-29T04:25:24.037 に答える