java - JAXB 将多个 XML 元素解码为单个类

标签 java xml jaxb eclipselink moxy

我有以下 XML 结构,它正在跨多个 XML 元素对单个概念进行建模。这种格式不受我控制。

<Output>
  <Wrapper>
    <Channel>
      <id>1</id>
      <type>x</type>
    </Channel>
    <Channel>
      <id>2</id>
      <type>y</type>
    </Channel>
    <ChannelName>
      <id>1</id>
      <name>Channel name</name>
    </ChannelName>
    <ChannelName>
      <id>2</id>
      <name>Another channel name</name>
    </ChannelName>
  </Wrapper>
</Output>

我想在我可以控制的数据库中对此建模,并且可以有一个更简单的 Channelid , typename领域。因此我想解码成一个 List<Channel>Wrapper 上类。

这可以用 @Xml... 来完成吗?自动注释?我目前正在使用 JAXB 解码为单独的 @XmlElement(name="Channel")@XmlElement(name="ChannelName")类列表,然后对 transient 进行后处理 ChannelName/nameChannel 上但我认为必须有一种更简单的自动化方法来映射这些元素。还是 XSLT 的工作?

了解 XML 以 HTTP 文件 POST 文件的形式出现并且我使用的是 Spring 3、Java 和 Hibernate 可能会有所帮助。我希望在 EclipseLink JAXB (MOXy) 中有所作为可能有帮助:)

最佳答案

@XmlElementWrapper 将完成这项工作:

@XmlElementWrapper(name="Wrapper")
@XmlElement(name="Channel")
private List<Channel> channels;

对于更高级的情况,您可以在 EclipseLink JAXB (MOXy) 中使用 @XmlPath 扩展:


这是我目前所拥有的。我仍在努力消除对辅助对象的需求。此示例需要 EclipseLink JAXB (MOXy) .

模型对象

您的模型对象是:

package example;

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

public class Wrapper {

    private List<Channel> channels = new ArrayList<Channel>();

    public List<Channel> getChannels() {
        return channels;
    }

    public void setChannels(List<Channel> channels) {
        this.channels = channels;
    }

}

和:

package example;

import javax.xml.bind.annotation.XmlID;

public class Channel {

    private String id;
    private String type;
    private String name;

    @XmlID
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

辅助对象

我目前的解决方案涉及一些辅助对象:

package example.adapted;

import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

import example.Channel;
import example.Wrapper;

@XmlRootElement(name="Output")
@XmlType(propOrder={"channels", "channelNames"})
public class AdaptedWrapper {

    private Wrapper wrapper = new Wrapper();
    private List<ChannelName> channelNames;

    @XmlTransient
    public Wrapper getWrapper() {
        for(ChannelName channelName : channelNames) {
            channelName.getChannel().setName(channelName.getName());
        }
        return wrapper;
    }

    @XmlElementWrapper(name="Wrapper")
    @XmlElement(name="Channel")
    public List<Channel> getChannels() {
        return wrapper.getChannels();
    }

    public void setChannels(List<Channel> channels) {
        wrapper.setChannels(channels);
    }

    @XmlElementWrapper(name="Wrapper")
    @XmlElement(name="ChannelName")
    public List<ChannelName> getChannelNames() {
        return channelNames;
    }

    public void setChannelNames(List<ChannelName> channelNames) {
        this.channelNames = channelNames;
    }

}

和:

package example.adapted;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlIDREF;

import example.Channel;

public class ChannelName {

    private String name;
    private Channel channel;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlIDREF
    @XmlElement(name="id")
    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }

}

演示代码

package example;

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import example.adapted.AdaptedWrapper;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(AdaptedWrapper.class);

        File xml = new File("input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        AdaptedWrapper adaptedWrapper = (AdaptedWrapper) unmarshaller.unmarshal(xml);
        Wrapper wrapper = adaptedWrapper.getWrapper();

        for(Channel channel : wrapper.getChannels()) {
            System.out.println(channel.getName());
        }
    }

}

关于java - JAXB 将多个 XML 元素解码为单个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5325362/

相关文章:

java - Scala 和 Java 实时系统

在 Firefox 和 IE 中使用 XSLT 将 XML 转换为 XML

php - 如何以编程方式将任何网页转换为 RSS 提要?

java - 通过 Maven 的 JAXB,具有多个具有空命名空间的模式

java - 使用 jaxb 外部绑定(bind)自定义时出错

java - 如何旋转绘图面板中绘制的一系列线条和形状?

java - 不兼容的类型 : int cannot be converted to Drawable

java - 在 Java 控制台中退格?

c# - 如何将 XML 映射到 C# 对象

java - 只是为了解码而削减了 JAXB?