【问题标题】:JAXB binding for xs:integer to Java Integer instead of BigIntegerxs:integer 的 JAXB 绑定到 Java Integer 而不是 BigInteger
【发布时间】:2017-05-05 21:25:08
【问题描述】:

应避免以下讨论。这个问题不是什么:

  • 使用 xs:int 代替 xs:integer。
  • 使用原始 int 而不是 Integer。
  • 为什么需要这个。
  • 如果等等,你会怎么做。

问题:

我想要一个 jaxb 绑定声明示例,以覆盖 xs:integer 到 Java BigInteger 的默认映射,以便 xjc 生成 Java Integer。

例如

<xs:attribute name="id" type="xs:integer"/>

应该产生

@XmlAttribute(name = "id")
Integer id;

而不是

@XmlAttribute(name = "id")
BigInteger id;

【问题讨论】:

  • 如果相应的文档元素包含 ≥ 2³¹ 的值,您希望 JAXB 做什么?
  • 不用担心。
  • 这个没有答案吗?我用谷歌找到的。

标签: java binding jaxb xjc


【解决方案1】:

您可以在绑定文件中添加以下内容:

<globalBindings>
    <javaType xmlType="xs:integer" name="java.lang.Integer"/> 
</globalBindings>

这将产生,例如:

@XmlAttribute(name = "id")
@XmlJavaTypeAdapter(Adapter1 .class)
protected Integer id;

public int getId() {
    if (id == null) {
        return new Adapter1().unmarshal("0");
    } else {
        return id;
    }
}

public void setId(Integer value) {
    this.id = value;
}

【讨论】:

    【解决方案2】:

    @JeroenVanMontfort 的答案是一种可行的方法,但是由于缺少命名空间减速和设置详细信息,因此无法按原样工作。如果您正在寻找有关此的更多详细信息,以下是详细信息。

    有多种方法可以创建绑定文件,但是您也可以创建嵌入式绑定,但为了这个问题,我将跳过该部分。但是,如果您想阅读详细信息,包括您可以从绑定文件中获得什么,请参阅blog by coderleaf

    以下是创建全局绑定的简单绑定文件,以确保将xs:integer 转换为java.lan.Integer 而不是BigInteger,并将枚举值的特定绑定定义为整数(这不是问题的一部分虽然添加只是为了描述混合绑定)

    <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://java.sun.com/xml/ns/jaxb https://java.sun.com/xml/ns/jaxb/bindingschema_2_1.xsd"
        version="2.1">
            <jxb:globalBindings>
                <jxb:javaType xmlType="xs:integer" name="java.lang.Integer" />
            </jxb:globalBindings>
            <jxb:bindings schemaLocation="../xsd/myService.xsd">
                <jxb:bindings node="//xs:simpleType[@name='DayOfWeek']/xs:restriction/xs:enumeration[@value='1']">
                    <jxb:typesafeEnumMember name="Monday" />
                </jxb:bindings>
                <jxb:bindings node="//xs:simpleType[@name='DayOfWeek']/xs:restriction/xs:enumeration[@value='2']">
                    <jxb:typesafeEnumMember name="Tuesday" />
                </jxb:bindings>
            </jxb:bindings>
        </jxb:bindings>
    

    以下是 xsd 示例(我只是手工制作,可能包含错误,请注意)

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://my.service.com/model"
        targetNamespace="http://my.service.com/model" elementFormDefault="qualified">
    
        <xs:element name="MyElement">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="field1" type="xs:integer"/>
                    <xs:element name="field2" type="tns:DayOfWeek"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:simpleType name="DayOfWeek">
            <xs:restriction base="xs:string">
                <xs:enumeration value="1" />
                <xs:enumeration value="2" />
            </xs:restriction>
        </xs:simpleType>
    </xs:schema>
    

    上面将创建类似这样的类(我不包括 toString、hash、equals 和其他函数以使其保持苗条)

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "MyElement", propOrder = {
        "field1",
        "field2"
    })
    public class MyElement implements Equals2, HashCode2, ToString2
    {
        @XmlElement(required = true, type = String.class)
        @XmlJavaTypeAdapter(Adapter1 .class)
        @XmlSchemaType(name = "integer")
        protected Integer field1;
        
        @XmlElement(name = "DayOfWeek", required = true)
        @XmlSchemaType(name = "string")
        protected DayOfWeek field2;
    
        public Integer getField1() {
            return field1;
        }
        public DayOfWeek getField2() {
            return field2;
        }    
    }
    

    还要注意枚举

    @XmlType(name = "DayOfWeek")
    @XmlEnum
    public enum DayOfWeek {
    
        @XmlEnumValue("1")
        Monday("1"),
        @XmlEnumValue("2")
        Tuesday("2");
        private final String value;
    
        DayOfWeek(String v) {
            value = v;
        }
    
        public String value() {
            return value;
        }
    
        public static DayOfWeek fromValue(String v) {
            for (DayOfWeek c: DayOfWeek.values()) {
                if (c.value.equals(v)) {
                    return c;
                }
            }
            throw new IllegalArgumentException(v);
        }
    }
    

    【讨论】:

      【解决方案3】:

      对于全局覆盖,在您的绑定文件中使用它:

      <bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
          <globalBindings>
              <javaType xmlType="xs:integer" name="java.lang.Integer"/> 
          </globalBindings>
      </bindings>
      

      要覆盖特定类型的用法,请使用以下内容:

      <bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
          <bindings schemaLocation="../xsd/foo.xsd">
              <bindings node="//xs:complexType[@name='bar']/xs:attribute[@name='id']">
                  <property>
                      <baseType>
                          <javaType name="java.lang.Integer"/>
                      </baseType>
                  </property>
              </bindings>
          </bindings>
      </bindings>
      

      通过在node 属性中使用schemaLocation 和XPath 表达式,您可以根据需要限制覆盖。

      【讨论】:

        【解决方案4】:

        对于属性:

        <xs:attribute name="id" type="xs:int" />
        

        对于元素:

        <xs:element name="id" type="xs:int" minOccurs="0" />
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多