将XML映射到与XML结构不匹配的Java对象

时间:2014-04-01 15:20:35

标签: java xml jaxb unmarshalling moxy

我通过调用遗留系统获得了一个扁平的XML文档,我希望能够使用注释将其解组为多个Java对象(理想情况下)。

XML没有xsd,我想维护我的Java类的当前结构,因为它们映射到我从我的restful服务返回的JSON结构。

我已经看到了使用MOXy反向出现此问题的示例,但没有完全解决此问题的示例。

所以给...

    <xml>
        <body>
            <a>A</a>
            <b>B</b>
            <c>C</c>
            <d>D</d>
            <e>E</e>
        </body>
    </xml>

我想将这些值映射到

    public class wrapper {

        private Object1 one;
        private Object2 two;
        private Object3 thr;
    }

    public class Object1 {

        private String a;
        private String b;

    }

    public class Object2 {

        private String c;
        private String d;
    }

    public class Object3 {

        private String e;
    }

这种明显的,长期的方法是手动解析XML文档检索文本节点值并在我的java对象上设置它们,但我试图避免这种情况,因为XML相当大,我将不得不重复几个服务的过程。

任何需要大量人工处理的解决方案都会让我难以证明偏离当前的长手法。

提前致谢

1 个答案:

答案 0 :(得分:2)

相关的MOXy功能

MOXy目前支持使用@XmlPath(".")将子对象的映射属性直接写入父对象元素中(参见:http://blog.bdoughan.com/2010/07/xpath-based-mapping.html)。

您的用例有什么意义

使用您的用例会让您感到棘手的是您在示例中增加了嵌套级别。我们今天不直接支持此功能,但我添加了一项增强请求(请参阅:http://bugs.eclipse.org/432029)。实现此功能后,您将能够执行以下操作:

@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class wrapper {

    @XmlPath("body")
    private Object1 one;

    @XmlPath("body")
    private Object2 two;

    @XmlPath("body")
    private Object3 thr;

}

解决方法

使用当前功能,您可以执行以下操作:

Java模型

@XmlRootElement(name="body")
@XmlAccessorType(XmlAccessType.FIELD)
public class wrapper {

    @XmlPath(".")
    private Object1 one;

    @XmlPath(".")
    private Object2 two;

    @XmlPath(".")
    private Object3 thr;

}

<强>演示

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource source = new StreamSource("input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(source);
        while(!(xsr.isStartElement() && "body".equals(xsr.getLocalName()))) {
            xsr.next();
        }

        JAXBContext jc = JAXBContext.newInstance(wrapper.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        wrapper result = (wrapper) unmarshaller.unmarshal(xsr);
     }

}

了解更多信息