如何在JAXB中将多个元素映射到单个类

时间:2011-09-12 18:17:25

标签: java mapping jaxb unmarshalling

我在输入时遵循XML:

<root>
 <response1></response1>
</root>

<root>
 <response2></response2>
</root>

并且可能有很多响应标记,我需要将每个响应标记映射到单个Response类,因为它们具有几乎相同的结构。

在JAXB中做起来容易吗?

感谢。

5 个答案:

答案 0 :(得分:5)

可以使用@XmlElements注释完成此操作:

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

    @XmlElements({
        @XmlElement(name="response1", type=Response.class),
        @XmlElement(name="response2", type=Response.class),
        @XmlElement(name="response3", type=Response.class)
    })
    private Response response;

}

答案 1 :(得分:2)

嗯,当然。在XSD文件中,首先定义一个类型:

<xs:complexType name="response">
  <!-- define type here -->
</xs:complexType>

现在使用它来定义你的元素:

<xs:element name="response1" type="response"/>
<xs:element name="response2" type="response"/>
<!-- and so on and so forth -->

答案 2 :(得分:2)

我让它以这种方式工作。它使用XMLStreamReader作为源,并使用StreamReaderDelegate来拦截和重写元素名称,然后才能到达jaxb。

主要测试类:

package grimbo.test.jaxb;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;

public class JaxbTest {
    public static <T> T unmarshal(Class<T> clazz, InputStream inputStream) throws JAXBException, XMLStreamException,
            FactoryConfigurationError {
        XMLStreamReader r = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
        MyXMLStreamReader my = new MyXMLStreamReader(r);
        String packageName = clazz.getPackage().getName();
        JAXBContext jc = JAXBContext.newInstance(packageName);
        Unmarshaller u = jc.createUnmarshaller();
        return (T) u.unmarshal(my);
    }

    public static void main(String[] args) throws Exception {
        String xml1 = "<root>" + "<response1>test1</response1>" + "</root>";
        String xml2 = "<root>" + "<response2>test2</response2>" + "</root>";

        Object ob = unmarshal(Response.class, new ByteArrayInputStream(xml1.getBytes()));
        System.out.println(ob);

        ob = unmarshal(Response.class, new ByteArrayInputStream(xml2.getBytes()));
        System.out.println(ob);
    }

    static class MyXMLStreamReader extends StreamReaderDelegate {
        public MyXMLStreamReader(XMLStreamReader reader) {
            super(reader);
        }

        public QName getName() {
            QName qname = super.getName();
            return qname;
        }

        public String getLocalName() {
            String localName = super.getLocalName();
            if (localName.matches("response\\d+")) {
                return "response";
            }
            return localName;
        }
    }
}

Response类是:

package grimbo.test.jaxb;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "root", namespace = "")
public class Response {
    String response;

    public String getResponse() {
        return response;
    }

    public void setResponse(String response) {
        this.response = response;
    }

    @Override
    public String toString() {
        return "Response [response=" + response + "]";
    }
}

此包中还有一个jaxb.in​​dex文件,它声明了Response类:

Response

测试的输出是:

Response [response=test1]
Response [response=test2]

这有什么帮助吗?

答案 3 :(得分:1)

最简单的做法是将响应元素设置为模式中的无界列表,然后一旦创建了绑定,就可以遍历响应节点列表。

答案 4 :(得分:0)

我尝试使用上面提到的相同格式的JAXB将多个标记映射到单个类。                      现在使用它定义元素:

<xs:element name="response1" type="response"/>
<xs:element name="response2" type="response"/>
<!-- and so on and so forth -->

While unmarshalling JAXB validates the XML(format) with response class  format mentioned in XSD file ,but its is giving me JAXB.element class object instead of response object.

Please suugest with answer..