【问题标题】:Marshalling XML file to Java pojo/domain object将 XML 文件编组为 Java pojo/域对象
【发布时间】:2011-12-20 15:00:13
【问题描述】:

我有一个旧的 Access 数据库,它基本上是一个平面文件。我想将数据迁移到我的新奇特、面向对象、基于休眠的奇迹应用程序。

数据以 XML 文件的形式提供,我想映射到三个单独的 java pojo。我计划使用 JAXB 来执行此操作,特别是使用 @xmlelement 注释。但是 XML 文件的结构不是最优的,在我的 pojos 中,我将数据分成三个不同的对象。

JAXB 会帮助解决这个问题吗?我是否需要使用 jaxb 根据现有的模式/xml 文件(不是 oo)简单地创建 java pojo。然后创建 apdater 类/层将数据放入我的三个 pojo 中?或者我可以直接从 xml 文件映射到 3 个具有正确配置/注释的 pojo 吗?

【问题讨论】:

  • 您能否提供有关您的 XML 和对象外观的更多详细信息?
  • @BlaiseDoughan 有什么不同吗?我有 1000 行/根元素,每个元素都有 20 个子元素/列。我已将二十个子元素拆分为三个独立的 pojo。就是这样。看起来我必须创建与 xml 匹配的 pojo,然后将一个 pojo 映射到其他三个 ...
  • 取决于您正在寻找的答案的质量:)。这 3 个 POJO 是如何相互关联的?
  • 您不需要手动创建中介 pojo。您可以使用 xjc。看我的回答。
  • @BlaiseDoughan 3 个 pojo,好吧,“a”引用了“b”,它引用了“c”……(它们也是休眠实体)

标签: java xml jaxb marshalling


【解决方案1】:

注意:我是EclipseLink JAXB (MOXy) 领导,也是JAXB 2 (JSR-222) 专家组的成员。

假设您的 XML 文档如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<rows>
    <row>
        <col1>a1</col1>
        <col2>b1</col2>
        <col3>c1</col3>
    </row>
    <row>
        <col1>a1</col1>
        <col2>b2</col2>
        <col3>c2</col3>
    </row>
</rows>

您可以利用 MOXy 的 @XmlPath 注释并执行类似的操作。 EclipseLink 还包括一个JPA implementation

您需要创建一个 Root 对象来保存所有内容:

package forum8577359;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Rows {

    @XmlElement(name="row")
    private List<A> rows;

}

一个

由于ABC 对象的内容都在同一级别,您可以使用MOXy 的@XmlPath 注释并指定"." XPath。这告诉 MOXy 对象和它所引用的对象出现在同一级别:

package forum8577359;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlAccessorType(XmlAccessType.FIELD)
public class A {

    private String col1;

    @XmlPath(".")
    private B b;

}

B

我们再次使用@XmlPath(".") 来映射BC 之间的关系:

package forum8577359;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlAccessorType(XmlAccessType.FIELD)
public class B {

    private String col2;

    @XmlPath(".")
    private C c;

}

C

package forum8577359;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class C {

    private String col3;

}

演示

以下演示代码可用于运行此示例:

package forum8577359;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum8577359/input.xml");
        Rows rows = (Rows) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(rows, System.out);
    }

}

jaxb.properties

要将 MOXy 指定为您的 JAXB 提供程序,您需要在与您的域类相同的包中包含一个 jaxb.properties 文件,并带有以下条目:

javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory

更多信息

【讨论】:

  • wowzers,你的答案比我打算写的代码要大。非常感谢。
【解决方案2】:

在不知道您的问题的细节的情况下...应该可以,但听起来这可能是您想要编写模式的情况,使用xjc 生成绑定对象,解组生成的绑定对象,然后在 java 中转换为您的域对象(或如果适用,直接使用生成的对象)。

【讨论】:

    【解决方案3】:

    JAXB 通常会有所帮助。即使您是手动编写类和注释,我认为它比使用 DOM API 解析花费的时间更少。

    此外,您可以使用 JAXB 自动生成值对象。我认为这是您应该尝试的方法。首先,您应该从您的 XML 生成 XSD 文件(除非您已经有一个)。然后您应该基于 XSD 生成值对象。然后只需解析文件。 2行代码,你就完成了。

    【讨论】:

    • 您好,感谢您对此的回复。关于Moxy/JAXB,我有点陷入以下问题。如果你有机会,你能看看并提供你的回应吗? stackoverflow.com/q/67648941/7584240
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    相关资源
    最近更新 更多