简体   繁体   English

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

[英]How to map simple Java class's field names into sequence of name-value pairs

I have a very simple class that I want to transmit as XML. 我有一个非常简单的类,希望以XML形式传输。 The accepted XML format is a list of fields made of name attribute and sequence of string values. 可接受的XML格式是由名称属性和字符串值序列组成的字段列表。 Can I annotate my class so that I can: 我可以注释我的班级,以便:

  1. Use class name as attribute "type" of xml entity 使用类名称作为xml实体的属性“类型”
  2. Use class fields names as attribute "name" in xml sequence of Fields ? 在字段的xml序列中使用类字段名称作为属性“名称”?

What would be the recommended way? 推荐的方法是什么? The example class in question: 有问题的示例类:

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

in xml format: 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>

What I would like to avoid is having to declare a Field class, and put a list of them in my object, because I want to enforce a particular set of required fields. 我要避免的是必须声明一个Field类,并将它们的列表放在我的对象中,因为我想强制执行一组特定的必填字段。

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

For completeness these are supported schemas: 为了完整起见,以下是受支持的架构:

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

I suppose that you realize that what you want is a significant deviation from XML's standard procedure, ignoring the concepts underlying the design of this data format, and the Java Architecture for XML Binding as well. 我想您已经意识到,您想要的是与XML标准过程的重大偏离,而忽略了此数据格式的设计基础以及XML绑定的Java体系结构。 Thus, class fields are meant to be represented by element names. 因此,类字段应由元素名称表示。 Also, using an XML structure that does not reflect the structure of the data (class MyEntityType) or, vice versa, using a class that does not correspond to the structure of the data creates a gap that no out-of-the-box tool can handle. 同样,使用不反映数据结构的XML结构(类MyEntityType),或者反之亦然,使用不对应数据结构的类会产生空白,没有现成的工具可以处理。 There are neither annotations nor external bindings to achieve this completely different structure. 既没有注释也没有外部绑定来实现这种完全不同的结构。

There is, of course, the JAXB feature of adapter, which helps to replace one Java type by another, but here one has to replace the entire Java structure before it can be marshalled into XML. 当然,还有适配器的JAXB功能,该功能有助于将一种Java类型替换为另一种Java类型,但是这里必须先替换整个Java结构,然后才能将其编组为XML。

Your XML schema (with a small correction) generates the required Java classes EntityComplexType, FieldsComplexType and FieldComplexType (which I don't paste here). 您的XML模式(稍作修正)会生成所需的Java类EntityComplexType,FieldsComplexType和FieldComplexType(我不会在此处粘贴)。

A Java class EntityAdapter can be written in the spirit of an adapter: 可以按照适配器的精神来编写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;
    }
}

And marshalling proceeds as usual, with the addition of transforming the MyEntityType object to an EntityComplexType object: 编组照常进行,另外还有将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, ... );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM