【问题标题】:Java unmarshlling XML to Object which are dynamicJava将XML解组为动态的对象
【发布时间】:2011-11-08 13:44:04
【问题描述】:

我正在寻找从 XML 定义中创建和加载 JAVA 对象的最佳工具/方法。 我检查了JAXB,看起来很不错,但没有找到一种方法来处理属性是动态的或不时更改的实体,所以想要有类似自动处理实体的方式,无需将 Object 转换为预定义的 Entity 对象。存在这样的东西吗?

工作流程就像这样从 XML 为每个具有动态属性集的实体创建类和/或为这些实体创建 ORM 映射部分,然后所有操作检索/存储到数据库中,或者可能会使用一些 NoSQL 解决方案,例如MongoDB。

【问题讨论】:

标签: java architecture orm mapping jaxb


【解决方案1】:

那么,您基本上是在尝试使用 XML 文件制作 POJO(普通的旧 Java 对象)?它们就像数据类,对吧?

我是XStream 的忠实拥护者,它非常易于使用,并且在您不需要验证的情况下非常有用。当需要对模式进行验证时,我使用了Castor。我只是使用 XStream 将对象保存到 xml 文件,然后我可以从任何地方读回它,即使我更改了与对象关联的数据值(我认为这就是“动态属性集”的意思,对吧?)。

【讨论】:

  • 是的,我正在尝试制作 POJO 对象并使用它们,该 XML 文件包含每个实体的定义、模式的外观,并且模式应该不时更改。我需要建立一种动态的方式来管理 POJO 对象。所有数据都将存储在 MongoDB 中,这个 POJO 对象将从那里加载它们,所以这个 XML 只包含 POJO 对象的定义。不需要验证。
【解决方案2】:

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


查看以下 EclipseLink 示例。它演示了如何在 JPA 和 JAXB 实现中使用动态属性:


选项 #1 - 具有动态属性的静态对象

MOXy 有一个@XmlVirtualAccessMethods 扩展,允许您将映射中的条目映射到 XML。这允许您将属性添加到静态类。在下面的示例中,Customer 类具有“真实”名称属性,并且可能具有许多“虚拟”属性。

package blog.metadatasource.refresh;

import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlVirtualAccessMethods;

@XmlRootElement
@XmlType(propOrder={"firstName", "lastName", "address"})
@XmlVirtualAccessMethods
public class Customer {

    private String name;
    private Map<String, Object> extensions = new HashMap<String, Object>();

    public String getName() {
        return name;
    }

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

    public Object get(String key) {
        return extensions.get(key);
    }

    public void set(String key, Object value) {
        extensions.put(key, value);
    }

}

虚拟属性是通过 MOXy 的 XML 元数据定义的。在下面的示例中,我们将添加两个属性:middleName 和 shippingAddress。

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="blog.metadatasource.refresh">
    <java-types>
        <java-type name="Customer">
            <java-attributes>
                <xml-element
                    java-attribute="middleName"
                    name="middle-name"
                    type="java.lang.String"/>
                <xml-element
                    java-attribute="shippingAddress"
                    name="shipping-address"
                    type="blog.metadatasource.multiple.Address"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

更多信息


选项 #2 - 动态对象

MOXy 还提供完整的动态对象模型:

DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, null, null, null);

Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DynamicEntity customer = (DynamicEntity) unmarshaller.unmarshal(inputStream);

DynamicEntity address = jaxbContext.newDynamicEntity("org.example.Address");
address.set(street, "123 A Street");
address.set(city, "Any Town");
customer.set("address", address);

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(customer, System.out);

更多信息

【讨论】:

  • 看起来不错,但是如果我们不知道未来 POJO 对象的确切结构,有没有办法管理事情,在您的示例中,您使用“firstName”、“lastName”、“address”修复了,如果我想让它动态呢?
  • @vaske - 使用选项 #1(具有动态属性的静态模型),名称属性是静态的(使用 getName()/setName("Jane") 访问,中间名属性是动态的(使用 @ 访问) 987654339@/set("middleName", "Anne").
  • 谢谢,就是这样,还有关于类名,我将从 XML 文件中提取它们,基本上我所有的实体都在一个文件中,定义然后我将读取它并创建 POJO 对象并将其用作应用程序中的映射源。
  • MOXy 提供一个 XML 映射文件 (blog.bdoughan.com/2010/12/…),可用于映射静态类、为静态类添加动态属性 (blog.bdoughan.com/2011/06/…) 或引导完全动态模型 (wiki.eclipse.org/EclipseLink/UserGuide/MOXy/Runtime/… )。这是你要找的吗?
  • 最后一个似乎是我一直在寻找的东西。主要问题实际上是从 XML 文件中读取结构然后使用该结构来处理从第三方获取的数据,基本上我不确定这些是否会帮助我,因为我认为这会......但正在调查:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 2016-12-02
  • 2018-11-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多