当前位置: 首页 > 面试题库 >

JAXB将多个XML元素解组到单个类中

陆耀
2023-03-14
问题内容

我具有以下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>

我想在一个数据库中,我确实有控制权,并可以有一个更简单的模型此Channelidtypename领域。因此,我想List<Channel>Wrapper课堂上解组。

可以通过@Xml...注释自动完成吗?我目前正在使用JAXB解组到单独的列表@XmlElement(name="Channel")@XmlElement(name="ChannelName")类列表,然后在ChannelName/name上对瞬态进行后处理,Channel但是我认为必须有一种更简便的自动方式来映射这些元素。还是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扩展:

  • http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html

这是我到目前为止所拥有的。我仍在尝试消除对辅助对象的需要。该示例需要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());
        }
    }

}


 类似资料:
  • 问题内容: 我发现很多文章描述了如何将XML元素序列编组到HashMap,只要它们在“父”元素内。但是,我不希望它直接与root元素下的孩子一起工作! 选项1-运作: 选项2 -难道 不 工作: 检查: 检查: CheckMapType: ChecksAdapter: 这是(一些虚拟测试行)我如何生成类/调用解组的方法: 关于如何使选项2起作用的任何想法吗?当使用列表而不是Map时它可以工作,但是

  • 我正在尝试解组一个包含多个同名元素的XML文档。我不确定是否需要创建bean的Arraylist并将其传递给解组器。我希望有人能给我一些建议来解决这个问题。我试图解析的XML是一个SOAP响应,但我去掉了信封,所以我只有它的主体,它看起来是这样的: 这是从一个包含50多个字段的表返回的,但我创建了一个testBean,并且我定义了fkdevice只是为了使其简单,我的bean看起来像这样: 这给了

  • 我认为这对真正理解JAXB绑定文件的人来说很容易... 如何配置JAXB将多个元素解组到同一个类中? 注意:我想避免在我的项目中添加另一个依赖项(比如MOXy)。理想情况下,这可以通过注释或自定义绑定文件来实现。 我有一个XML文档,其中包含许多相同元素的变体——每个元素都有完全相同的属性。使用下面的示例,我只关心“员工”,但XML指定了“董事、经理和员工”。为了我们的目的,这些都是同一个父类的子

  • 问题内容: 我认为对于真正了解JAXB绑定文件的人来说这很容易… 基本问题 如何配置JAXB将多个元素解组到同一类中? 注意:我想避免向我的项目中添加另一个依赖项(例如MOXy)。 理想情况下,这可以通过注释或自定义绑定文件来完成。 背景 我有一个XML文档,其中包含许多相同元素的变体,每个变体具有完全相同的属性。在下面的示例中,我只关心“雇员”,但是XML指定了“董事,经理和职员”。出于我们的目

  • 我想让JAXB列表到xml,其中命名空间只出现在根元素中,而不是在任何其他元素中: 我已经尝试了package level @XmlSchema,但是我一定是做错了什么,因为没有显示任何东西。 这是我的根元素类: 我还有以下包-info.java:

  • 问题内容: 假设以下xml元素具有属性和浮点值: 为了解组它,我应该如何定义我的结构? XMLName属性的用法使我感到困惑。什么时候应该将其放置在结构中,何时将其作为标签包装? 问题答案: 在下面,您可以找到解组给定数据的代码。 在删除空格之前,无法正确解组浮点值。 可以使用“,chardata”注释引用标记的内容。 您无需在结构中指定字段,只要它不模糊应使用哪种结构即可。