【问题标题】:How to map simple Java class's field names into sequence of name-value pairs如何将简单的 Java 类的字段名称映射到名称-值对序列
【发布时间】:2015-10-18 01:18:41
【问题描述】:

我有一个非常简单的类,我想将它作为 XML 传输。可接受的 XML 格式是由名称属性和字符串值序列组成的字段列表。我可以注释我的课程以便我可以:

  1. 使用类名作为xml实体的属性“类型”
  2. 在字段的 xml 序列中使用类字段名称作为属性“名称”?

推荐的方法是什么?有问题的示例类:

class MyEntityType {
    public List<String> myField1; // = {"A", "B"}
    public List<String> myField2; // = {"C", "D"}
}

xml格式:

<Entity type="MyEntityType">
    <Fields>
        <Field name="myField1">
            <Value>A</Value>
            <Value>B</Value
        </Field>
        <Field name="myField2">
            <Value>C</Value>
            <Value>D</Value>
        </Field>
    </Fields>
</Entity>

我想避免的是必须声明一个 Field 类,并将它们的列表放在我的对象中,因为我想强制执行一组特定的必填字段。

class MyEntityType {
    public static class Field {
        String name;
        String values
    }
    public List<Fields> fields;
}

为了完整起见,这些是受支持的架构:

<xs:complexType name="EntityComplexType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:sequence>
    <xs:element name="Fields" type="FieldsComplexType" />
  </xs:sequence>
  <xs:attribute name="Type" type="xs:string" use="required" />
</xs:complexType>

<xs:complexType name="FieldsComplexType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:sequence>
    <xs:element name="Field" type="FieldComplexType" maxOccurs="unbounded" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="FieldComplexType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:sequence>
    <xs:element name="Value" minOccurs="0" maxOccurs="unbounded">
      <xs:complexType>
        <xs:simpleContent>
          <xs:extension base="xs:string">
            <xs:attribute name="Alias" type="xs:string" use="optional" />
            <xs:attribute name="ReferenceValue" type="xs:string" use="optional" />
          </xs:extension>
        </xs:simpleContent>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
  <xs:attribute name="Name" use="required" />
</xs:complexType>

【问题讨论】:

  • 您的 XML Schema 文件与 XML 示例不匹配。

标签: java xml jaxb


【解决方案1】:

我想您已经意识到您想要的是与 XML 标准过程的重大偏差,而忽略了这种数据格式设计的基础概念,以及用于 XML 绑定的 Java 体系结构。因此,类字段意味着由元素名称表示。此外,使用不反映数据结构的 XML 结构(MyEntityType 类),反之亦然,使用不符合数据结构的类会造成没有开箱即用工具的差距可以处理。既没有注释也没有外部绑定来实现这种完全不同的结构。

当然,还有适配器的 JAXB 特性,它有助于将一种 Java 类型替换为另一种,但这里必须替换整个 Java 结构才能将其编组为 XML。

您的 XML 架构(稍作修正)生成所需的 Java 类 EntityComplexType、FieldsComplexType 和 FieldComplexType(我不在这里粘贴)。

可以按照适配器的精神编写 Java 类 EntityAdapter:

public class EntityAdapter {
    public MyEntityType unmarshal(EntityComplexType v){
        // ...
        return new MyEntityType();
    }
    public EntityComplexType marshal(MyEntityType v){
        EntityComplexType ect = new EntityComplexType();
        ect.setType( v.getClass().getSimpleName() );
        FieldsComplexType fct = new FieldsComplexType();
        ect.setFields( fct );
        FieldComplexType field1 = new FieldComplexType();
        fct.getField().add( field1 );
        field1.setName( "myField1" );
        for( String s: v.getMyField1() ){
            field1.getValue().add( s );
        }
        FieldComplexType field2 = new FieldComplexType();
        fct.getField().add( field2 );
        field2.setName( "myField2" );
        for( String s: v.getMyField2() ){
            field2.getValue().add( s );
        }
        return ect;
    }
}

编组照常进行,除了将 MyEntityType 对象转换为 EntityComplexType 对象之外:

MyEntityType met = ...;
EntityAdapter adapter = new EntityAdapter();
EntityComplexType ect = adapter.marshal( met );
ObjectFactory of = new ObjectFactory();
JAXBElement<EntityComplexType> jbe = of.createEntityComplexType( ect );
JAXBContext jc = JAXBContext.newInstance( PACKAGE );
Marshaller m = jc.createMarshaller();
m.marshal( jbe, ... );

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 2019-10-12
    • 2018-07-29
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    相关资源
    最近更新 更多