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

发布于 2024-12-04 05:31:05 字数 298 浏览 0 评论 0原文

我在输入上有以下 XML:

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

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

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

在 JAXB 中做起来容易吗?

谢谢。

I have following XML on input:

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

or

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

And there is possibly a lot of response tags each of which I need to map to a single Response class because they have almost the same structure.

Is it easy to do in JAXB?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初吻给了烟 2024-12-11 05:31:05

这可以通过 @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;

}

This could be done with the @XmlElements annotation:

@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;

}
所谓喜欢 2024-12-11 05:31:05

嗯,当然。在 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 -->

Well, sure. In XSD file, define a type first:

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

Now define your elements using it:

<xs:element name="response1" type="response"/>
<xs:element name="response2" type="response"/>
<!-- and so on and so forth -->
影子是时光的心 2024-12-11 05:31:05

我让它以这种方式工作。它使用 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]

这有什么帮助吗?

I got it to work this way. It uses an XMLStreamReader as the source, and a StreamReaderDelegate to intercept and rewrite the element names before they reach jaxb.

The main test class:

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;
        }
    }
}

The Response class is:

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 + "]";
    }
}

And there's a jaxb.index file in this package too, that declares the Response class:

Response

The output of the test is:

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

Is this any help?

清旖 2024-12-11 05:31:05

在我看来,最简单的事情是将响应元素设置为架构中的无界列表,然后一旦创建了绑定,您就可以迭代响应节点列表。

The easiest thing to do imo would be to make the response element an unbounded list in your schema then once you have created your bindings you can iterate throught the list of response nodes.

此生挚爱伱 2024-12-11 05:31:05

我尝试使用具有上述相同格式的 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.. 

I tried to map multiple tag to single class using JAXB with same format mention above.

Now define your elements using it:

<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.. 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文