Java将XML解组为动态的对象

2022-01-19 00:00:00 mapping orm architecture java jaxb

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

I'm looking for best tool/way to create and load JAVA objects from XML definitions. I had checked out JAXB, seems pretty nice, but didn't find is there a way to work with Entities which properties are dynamic, or changed from time to time, so want to have something like automatic way of working with entities, without converting Object into predefine Entity object. Does something like that exists?

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

Workflow would be like this read from XML create class for each Entity with dynamic set of attributes and/or create ORM mapping part for those entities and then all manipulation retrieve/store into db or probably will going to use some NoSQL solution like MongoDB.

推荐答案

注意:我是EclipseLink JAXB (MOXy) 领导者和 JAXB 2 (JSR-222) 专家组.

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

Check out the following EclipseLink example. It demonstrates how to use dynamic properties with both the JPA and JAXB implementations:

  • http://wiki.eclipse.org/EclipseLink/Examples/MySports

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

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

MOXy has an @XmlVirtualAccessMethods extension which allows you to map entries in a map to XML. This allows you to add properties to a static class. In the example below the Customer class has a "real" name property and may have many "virtual" properties.

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.

The virtual properties are defined via MOXy's XML metadata. In the example below we will add two properties: middleName and 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>

更多信息

  • http://blog.bdoughan.com/2011/06/extensible-models-with-eclipselink-jaxb.html
  • http://blog.bdoughan.com/2011/06/moxy-extensible-models-multi-tenant.html
  • http://blog.bdoughan.com/2011/06/moxy-extensible-models-multiple.html
  • http://blog.bdoughan.com/2011/06/moxy-extensible-models-refresh-example.html

选项 #2 - 动态对象

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

MOXy also offers full dynamic object models:

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

更多信息

  • http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy
  • http://wiki.eclipse.org/EclipseLink/Examples/MOXy/Dynamic

相关文章