将XML映射到与XML结构不匹配的Java对象 [英] Mapping XML to Java object that doesn't match XML structure

查看:132
本文介绍了将XML映射到与XML结构不匹配的Java对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过调用遗留系统获得了一个平面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;
私有Object2两个;
private Object3 thr;
}

公共类Object1 {

private String a;
private String b;

}

公共类Object2 {

private String c;
private String d;
}

public class Object3 {

private String e;
}

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



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



提前致谢

解决方案

相关的MOXy功能



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



你的用例有什么意义



Wh使你的用例变得棘手的是你在你的例子中有一个额外的嵌套级别。我们今天不直接支持此功能,但我添加了增强请求(请参阅: http://bugs.eclipse。组织/ 432029 )。实现此功能后,您将能够执行以下操作:

  @XmlRootElement(name =xml)
@XmlAccessorType(XmlAccessType.FIELD)
公共类包装器{

@XmlPath(body)
private Object1 one;

@XmlPath(body)
private Object2 two;

@XmlPath(body)
private Object3 thr;

}



解决方法



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



Java模型

  @XmlRootElement(name =body)
@XmlAccessorType(XmlAccessType.FIELD)
公共类包装器{

@XmlPath (。)
私有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 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);
}

}

更多信息




I get a flat XML document from a call to a legacy system and I would like to be able to unmarshal it into multiple Java objects (ideally) using annotations.

There is no xsd with the XML and I want to maintain the current structure of my Java classes because they map to the structure of the JSON I am returning from my restful service.

I have seen examples of this problem in reverse using MOXy, but no examples of this problem exactly.

So given ...

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

I would like to map these values to

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

The obvious, long hand way of doing this is to manually parse through the XML document retrieving text node values and setting them on my java objects, but I am trying to avoid this as the XML is fairly large and I will have to repeat the process for several services.

Any solutions that require a significant amount of manual processing will make it hard for me to justify a departure from the current long hand method.

Thanks in advance

解决方案

Related MOXy Functionality

MOXy currently supports writing the mapped properties of a child object directly into the parent objects element using @XmlPath(".") (see: http://blog.bdoughan.com/2010/07/xpath-based-mapping.html).

What's Interesting About Your Use Case

What makes it tricky with your use case is that you have an added level of nesting in your example. We don't support this directly today, but I have added an enhancement request (see: http://bugs.eclipse.org/432029). When this is implemented you will be able to do something like:

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

    @XmlPath("body")
    private Object1 one;

    @XmlPath("body")
    private Object2 two;

    @XmlPath("body")
    private Object3 thr;

}

Work Around

With current functionality you could do the following:

Java Model

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

    @XmlPath(".")
    private Object1 one;

    @XmlPath(".")
    private Object2 two;

    @XmlPath(".")
    private Object3 thr;

}

Demo

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

}

For More Information

这篇关于将XML映射到与XML结构不匹配的Java对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆