对需要带有模式的整数的元素使用 JAXB 生成的类 [英] Using JAXB generated class for an element that requires an integer with a pattern

查看:44
本文介绍了对需要带有模式的整数的元素使用 JAXB 生成的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 XML 架构中有一个元素定义如下:

I have an element in my XML Schema that is defined as follows:

<xs:complexType name="MyNumberCodeType">
    <xs:sequence>
        <xs:element name="Code" type="NumberCodeValueType" maxOccurs="unbounded" />
    </xs:sequence>
</xs:complexType>

NumberCodeValueType 在哪里:

Where NumberCodeValueType is:

<xs:simpleType name="NumberCodeValueType">
    <xs:restriction base="xs:int">
        <xs:pattern value="[0-7]{7}"/>
    </xs:restriction>
</xs:simpleType>

也就是说,我的号码可以以0开头.我不能修改这个架构.我正在使用 JAXB 来生成我的 Java 类.不幸的是,Code 元素的访问器将一个整数列表作为参数,这意味着所有前导 0 都被去除了(因为,据我所知,在 Java 中,当使用整数类型)!

That is, my number can start with leading 0s. I can NOT modify this schema. I am using JAXB to generate my Java classes. Unfortunately, the accessor for the Code element takes a list of integers as the argument which means all leading 0s are stripped off (because, from what I can tell, there's no way to keep leading 0s in Java when using an integer type)!

有什么办法可以解决这个问题吗?

Is there any way I can fix this?

感谢您的帮助!

推荐答案

您可以执行以下操作:

NumberFormatter

您可以通过编写自己的格式化程序来做到这一点:

You can do this by writing your own formatter:

package forum7182533;

public class NumberFormatter {

    public static String printInt(Integer value) {
        String result = String.valueOf(value);
        for(int x=0, length = 7 - result.length(); x<length; x++) {
            result = "0" + result;
        }
        return result;
    }

    public static Integer parseInt(String value) {
        return Integer.valueOf(value);
    }

}

XMLSchema (format.xsd)

然后,当您要从 XML 架构生成类时:

Then when you are going to generate your classes from your XML Schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="number" type="NumberCodeValueType" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="NumberCodeValueType">
        <xs:restriction base="xs:int">
            <xs:pattern value="[0-7]{7}" />
        </xs:restriction>
    </xs:simpleType>

</xs:schema>

bindings.xml

您将利用 JAXB 绑定文件来引用您的格式化程序:

You will leverage a JAXB bindings file to reference your formatter:

<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
    <jxb:bindings schemaLocation="format.xsd">
        <!--jxb:bindings node="//xs:simpleType[@name='NumberCodeValueType']" -->
        <jxb:bindings node="//xs:element[@name='number']">
            <jxb:property>
                <jxb:baseType>
                    <jxb:javaType name="java.lang.Integer"
                        parseMethod="forum7182533.NumberFormatter.parseInt" printMethod="forum7182533.NumberFormatter.printInt" />
                </jxb:baseType>
            </jxb:property>
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

XJC 电话

绑定文件在 XJC 调用中被引用为:

The bindings file is referenced in the XJC call as:

xjc -d out -p forum7182533 -b bindings.xml format.xsd

适配器 1

这将导致创建一个利用格式化程序的 XmlAdapter:

This will cause an XmlAdapter to be created that leverages your formatter:

package forum7182533;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class Adapter1
    extends XmlAdapter<String, Integer>
{


    public Integer unmarshal(String value) {
        return (forum7182533.NumberFormatter.parseInt(value));
    }

    public String marshal(Integer value) {
        return (forum7182533.NumberFormatter.printInt(value));
    }

}

根目录

XmlAdapter 将使用 @XmlJavaTypeAdapter 注释从您的域对象中引用:

The XmlAdapter will be referenced from your domain object using the @XmlJavaTypeAdapter annotation:

package forum7182533;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "number"
})
@XmlRootElement(name = "root")
public class Root {

    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    protected Integer number;

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer value) {
        this.number = value;
    }

}

演示

现在,如果您运行以下演示代码:

Now if you run the following demo code:

package forum7182533;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.setNumber(4);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }
}

输出

您将获得所需的输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <number>0000004</number>
</root>

这篇关于对需要带有模式的整数的元素使用 JAXB 生成的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆