java - 为原语自定义 jaxb 绑定(bind)

标签 java xml jaxb jaxb2

我有几个正在生成 jaxb 绑定(bind)的模式,它们可以自由使用 xs:integer。我希望将这些值绑定(bind)到 long/Long 而不是默认的 BigInteger。不幸的是,我没有能力修改模式。在我的绑定(bind)文件中添加一个简单的声明会导致 xs:integer 在所有情况下都绑定(bind)到 Long,即使它是必需的值也是如此:

<jaxb:javaType xmlType="xs:integer" name="long" />

当需要字段时,如何让 xs:integer 绑定(bind)到原语?

最佳答案

这很简单,你只需要在你的 .jxb 文件中有两个不同的绑定(bind),并使用正确的 XPath 选择器来找到需要映射到 Integer 和另一个 XPath 选择器,它将找到要映射到 int 的元素。

由于您还没有发布您的.xsd.xjb 文件,我将仅在一个小示例中展示它是如何工作的。假设我们有以下 .xsd 文件

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="user">
         <xs:complexType>
             <xs:sequence>
                 <xs:element type="xs:integer" name="age" minOccurs="1"/>
                 <xs:element type="xs:integer" name="balance" minOccurs="0"/>
             </xs:sequence>
         </xs:complexType>
    </xs:element>
</xs:schema>

所以从 .xsd 我们可以看到我们有一个 user 对象的定义,它有 age 属性,这是必需的(我们仍然也可以使用 use="optional"属性,但这并不重要)和可选的 balance 属性。

假设我们希望将 age 映射到 Java int 并将 balance 映射到 Integer

所以我们只需要一个绑定(bind)文件,它将找到所有 type 属性等于 xs:integerminOccurs 属性等于的节点到 1 并应用一些自定义映射规则并对所有 minOccurs 属性等于 0 的规则执行相同的操作。

<jxb:bindings version="2.0" 
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <jxb:bindings schemaLocation="schema.xsd">
        <!---Find all optional integers and map them to java.lang.Integer -->
        <jxb:bindings node="//xs:element[@minOccurs='0' and @type='xs:integer']" multiple="true">
            <xjc:javaType name="java.lang.Integer" adapter="adapters.IntegerAdapter" />
        </jxb:bindings>

        <!---Find all required integers and map them to primitive int -->
        <jxb:bindings node="//xs:element[@minOccurs='1' and @type='xs:integer']" multiple="true">
            <xjc:javaType name="int" adapter="adapters.IntAdapter" />
        </jxb:bindings>

    </jxb:bindings>
</jxb:bindings>

运行构建后就是这样(记住启用供应商自定义是添加 -extension 命令行参数)你会得到类似这样的东西。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"age",
"balance"
})
@XmlRootElement(name = "user")
public class User {

    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(IntAdapter.class)
    @XmlSchemaType(name = "integer")
    protected int age;
    @XmlElement(type = String.class)
    @XmlJavaTypeAdapter(IntegerAdapter.class)
    @XmlSchemaType(name = "integer")
    protected Integer balance;

    // getters setters will be here
}

另外,请注意,我没有为 adapters.IntegerAdapteradapters.IntAdapter 添加源,这部分是给你的)

关于java - 为原语自定义 jaxb 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45557708/

相关文章:

java - 在 Java 中使用 XML SOAP Web 服务

java - JAXB 2.x 和 Ant

java - Jersey/JAXB 讨厌矩形

javascript - XML解析远程服务器

Java quote.split 为仅 1 个单词

java - CSV 中的日期未按所需格式写入

java - 在 java 中遍历 EnumSet?

python - 将 xml 扁平化为 pandas 数据框,深度嵌套

jaxb - 如何忽略父类中的 JAXB 注释属性?

java - 无法在 Intellij 中指定主 list 属性