复杂类型的自定义JAXB映射

时间:2015-06-11 01:01:16

标签: java xml jaxb xjc

我有一个schema.xsd和bindings.xjb,我用它来生成带有xjc的类。我正在尝试让xjc生成一个Map的字段,其中Object vales是许多简单或复杂类型之一(xs:choice)。我不知道我想要完成的是否可行。以下是关键要求:

  1. 使用JAXB编组和解组对象
  2. 使用java.util.Map而不是java.util.List来跟踪ContactList中的Poc条目
  3. 将选项选项解析为存储在java.util.Map
  4. 中的值
  5. 选择选项可能是复杂类型
  6. 我会在这里给出示例代码:
    schema.xsd

    <?xml version="1.0"?>
    <!-- schema.xsd -->
    <xs:schema version="1.0"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               elementFormDefault="qualified">
    
      <xs:simpleType name="phonenumbertype">
        <xs:restriction base="xs:string"/>
      </xs:simpleType>
    
      <xs:complexType name="addresstype">
        <xs:sequence>
          <xs:element name="street" type="xs:string"/>
          <xs:element name="city" type="xs:string"/>
          <xs:element name="state" type="xs:string"/>
          <xs:element name="zipcode" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="poctype">
        <xs:sequence>
          <xs:element name="Name" type="xs:string"/>
          <xs:choice>
            <xs:element name="Address" type="addresstype"/>
            <xs:element name="Phone" type="phonenumbertype"/>
          </xs:choice>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="contactlisttype">
        <xs:sequence>
          <xs:element name="Poc" type="poctype" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
      </xs:complexType>
    
      <xs:element name="AddressBook">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="ContactList" type="contactlisttype"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    
    </xs:schema>
    

    bindings.xjb

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- bindings.xjb -->
    <jxb:bindings version="1.0"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema"
                  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
                  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                  jxb:extensionBindingPrefixes="xjc">
      <jxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
        <jxb:globalBindings fixedAttributeAsConstantProperty="true"
                            collectionType="java.util.ArrayList"
                            typesafeEnumBase="xs:NCName"
                            choiceContentProperty="true"
                            typesafeEnumMemberName="generateError"
                            enableFailFastCheck="false"
                            generateIsSetMethod="false"
                            underscoreBinding="asCharInWord">
          <!-- does not work: [ERROR] undefined simple type "contactlisttype". -->
          <xjc:javaType name="java.util.Map" xmlType="contactlisttype" adapter="xjc.MapAdapater"/>
        </jxb:globalBindings>
      </jxb:bindings>
    </jxb:bindings>
    

    document.xml中

    <?xml version="1.0" encoding="UTF-8"?>
    <AddressBook>
      <ContactList>
        <Poc>
          <Name>Person1</Name>
          <Address>
            <street>Home Street</street>
            <city>Home Town</city>
            <state>Home State</state>
            <zipcode>99999</zipcode>
          </Address>
        </Poc>
        <Poc>
          <Name>Person2</Name>
          <PhoneNumber>8006667777</PhoneNumber>
        </Poc>
      </ContactList>
    </AddressBook>
    

    现在xjc生成了这个:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "contactList"
    })
    @XmlRootElement(name = "AddressBook")
    public class AddressBook {
    
        @XmlElement(name = "ContactList", required = true)
        protected ContactList contactList;
    

    但是我想让它产生类似的东西:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "contactList"
    })
    @XmlRootElement(name = "AddressBook")
    public class AddressBook {
    
        @XmlElement(name = "ContactList", required = true)
        @XmlJavaTypeAdapter(MapAdapter.class)
        protected Map<String, Object> contactList;
    

    MapAdapter.java

    public class MapAdapter extends XmlAdapter<Map<String, Object>, ContactList>
    {
    
      @Override
      public ContactList unmarshal(Map<String, Object> v) throws Exception
      {
        ObjectFactory factory = new ObjectFactory();
        ContactList result = factory.createContactList();
        List<PointOfContact> contacts = result.getPoc();
        for (Map.Entry<String, Object> entry : v.entrySet())
        {
          PointOfContact poc = factory.createPointOfContact();
          String name = entry.getKey();
          Object address = entry.getValue();
    
          poc.setName(name);
          poc.setAddressOrPhone(address);
    
          contacts.add(poc);
        }
        return result;
      }
    
      @Override
      public Map<String, Object> marshal(ContactList v) throws Exception
      {
        // predictable iteration order maintains order of XML elements
        Map<String, Object> result = new LinkedHashMap<>();
        List<PointOfContact> contacts = v.getPoc();
        for (PointOfContact poc : contacts)
        {
          String key = poc.getName();
          Object value = poc.getAddressOrPhone();
          result.put(key, value);
        }
        return result;
      }
    
    }
    

0 个答案:

没有答案