Jaxb:xs:属性null值 [英] Jaxb: xs:attribute null values

查看:74
本文介绍了Jaxb:xs:属性null值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Reg:Jaxb

我基本上试图在JAXB中设置一个角色,它说无论何时遇到空字段,而不是在输出中忽略它,将它设置为空值。

I'm basically trying to set up a role in JAXB which says that whenever an null field is encountered, instead of ignoring it in the output, set it to an empty value.

对于xmlElement,我得到的答案就像我们需要使用nillable =true但是我们需要如何设置空值。通过谷歌搜索我发现我们需要使用use =optional但它不适用于我的情况。

For xmlElement I got answer like we need to use nillable="true" but for how we need to set the null value. by googling I found that we need to use use="optional" but its not working in my case.

我的xsd部分如下:

 <xs:attribute name="RomVersion" type="xs:string" use="required" /> 
 <xs:attribute name="MACAddress" type="xs:string" use="required" /> 
 <xs:attribute name="LargestFreeBlock" type="xs:unsignedInt" use="required" /> 
 <xs:attribute name="TimeSinceLastReset" type="xs:unsignedInt" use="optional" /> 
 <xs:attribute name="ResetReason" type="xs:string" use="optional" /> 
 <xs:attribute name="TimeStamp" type="xs:unsignedInt" use="optional" /> 
 <xs:attribute name="ECOList" type="xs:string" use="optional" /> 
 </xs:complexType>
 </xs:element>

如果有人知道,请尽快给我解决方案。

Please give me the solution ASAP if anyone knows.

推荐答案

从XML架构开始

前面的答案我描述了从Java对象开始时如何解决用例。根据您对该答案的评论,这个答案描述了当从XML模式生成模型时如何完成同样的事情。

In a previous answer I described how to solve your use case when starting from Java objects. Based on your comments to that answer, this answer describes how the same thing can be done when the model is generated from an XML schema.

XML架构(attributeAdapter.xsd)

XML Schema (attributeAdapter.xsd)

对于此示例,我们将使用以下XML架构:

For this example we will use the following XML schema:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema 
    elementFormDefault="qualified"
    targetNamespace="http://www.example.com/adapter" 
    xmlns:nytd="http://www.example.com/adapter" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="root">
        <xs:complexType>
            <xs:attribute name="foo" type="xs:string"/>
            <xs:attribute name="bar" type="xs:string"/>
        </xs:complexType>
    </xs:element>

</xs:schema>

StringConverter

StringConverter

我们需要定义一个类来进行特殊的字符串处理。对于此用例,我们希望在XML文档中将空字段/属性值视为空字符串():

We will need to define a class to do our special String handling. For this use case we want a null field/property value to be treated as empty String ("") in the XML document:

package com.example.adapter;

public class StringConverter {

    public static String parseString(String value) {
        if("".equals(value)) {
            return null;
        }
        return value;
    }

    public static String printString(String value) {
        if(null == value) {
            return "";
        }
        return value;
    }

}

Binding文件(attributeAdapterBinding.xml)

Binding File (attributeAdapterBinding.xml)

我们需要使用JAXB绑定文件来自定义类生成。下面的绑定文件将允许我们利用上面定义的StringConverter类:

We will need to use a JAXB binding file to customize the class generation. The binding file below will allow us to leverage the StringConverter class that we defined above:

<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:bindings schemaLocation="attributeAdapter.xsd">
        <jaxb:bindings node="//xs:element[@name='root']/xs:complexType">
            <jaxb:bindings node="xs:attribute[@name='foo']">
                <jaxb:property>
                    <jaxb:baseType>
                        <jaxb:javaType name="java.lang.String"
                            parseMethod="com.example.adapter.StringConverter.parseString"
                            printMethod="com.example.adapter.StringConverter.printString"/>
                    </jaxb:baseType>
                </jaxb:property>
            </jaxb:bindings>
            <jaxb:bindings node="xs:attribute[@name='bar']">
                <jaxb:property>
                    <jaxb:baseType>
                        <jaxb:javaType name="java.lang.String"
                            parseMethod="com.example.adapter.StringConverter.parseString"
                            printMethod="com.example.adapter.StringConverter.printString"/>
                    </jaxb:baseType>
                </jaxb:property>
            </jaxb:bindings>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

XJC致电

XJC call

我们将按如下方式进行XJC调用:

We will make our XJC call as follows:

xjc -d out -b attributeAdapterBinding.xml attributeAdapter.xsd

域模型(根)

Domain Model (Root)

我们在绑定文件中自定义的字段/属性将使用@XmlJavaTypeAdapter进行注释;

The fields/properties that we customized in the binding file will be annotated with @XmlJavaTypeAdapter;

package com.example.adapter;

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


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

    @XmlAttribute
    @XmlJavaTypeAdapter(Adapter1 .class)
    protected String foo;

    @XmlAttribute
    @XmlJavaTypeAdapter(Adapter2 .class)
    protected String bar;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String value) {
        this.foo = value;
    }

    public String getBar() {
        return bar;
    }

    public void setBar(String value) {
        this.bar = value;
    }

}

XmlAdapter (Adapter1)

XmlAdapter (Adapter1)

生成的XmlAdapter类如下所示。注意它如何利用我们的StringConverter类:

The generated XmlAdapter class will look something like the following. Note how it leverages our StringConverter class:

package com.example.adapter;

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

public class Adapter1 extends XmlAdapter<String, String> {

    public String unmarshal(String value) {
        return (com.example.adapter.StringConverter.parseString(value));
    }

    public String marshal(String value) {
        return (com.example.adapter.StringConverter.printString(value));
    }

}

演示

Demo

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

Now if we run the following demo code:

package com.example.adapter;

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.setFoo(null);
        root.setBar(null);

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

}

输出

Output

我们将获得所需的输出:

We will get the desired output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://www.example.com/adapter" foo="" bar=""/>

更新(备用约束文件)

或者,如果您希望适配器应用于 xsd:string 类型的所有属性,那么您可以使用看起来像这样的绑定文件;

Alternatively, if you wanted the adapter applied to all properties of type xsd:string then you could use an binding file that looked something like;

<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:globalBindings>
        <jaxb:javaType 
            name="String"
            xmlType="xs:string"
            parseMethod="com.example.adapter.StringConverter.parseString"
            printMethod="com.example.adapter.StringConverter.printString"/>
    </jaxb:globalBindings>

</jaxb:bindings>

这篇关于Jaxb:xs:属性null值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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