如何将简单Java类的字段名称映射到名称 - 值对的序列

时间:2015-10-16 19:18:24

标签: java xml jaxb

我有一个非常简单的类,我希望以XML格式传输。接受的XML格式是由name属性和字符串值序列组成的字段列表。我可以注释我的班级,以便我可以:

  1. 使用类名作为xml实体的属性“type”
  2. 在字段的xml序列中使用类字段名称作为属性“name”吗?
  3. 推荐的方式是什么?有问题的示例类:

    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>
    

1 个答案:

答案 0 :(得分:1)

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

当然,适配器的JAXB功能有助于将一种Java类型替换为另一种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, ... );