Reg:Jaxb
我基本上试图在JAXB中设置一个角色,它表示只要遇到空字段,而不是在输出中忽略它,将其设置为空值.
对于xmlElement我得到的答案就像我们需要使用nillable ="true"但我们需要如何设置null值.通过谷歌搜索我发现我们需要使用use ="optional"但它不适用于我的情况.
我的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>
Run Code Online (Sandbox Code Playgroud)
如果有人知道,请尽快给我解决方案.
从XML Schema开始
在前面的回答中,我描述了从Java对象启动时如何解决用例.根据您对该答案的评论,此答案描述了在从XML模式生成模型时如何完成相同的操作.
XML Schema(attributeAdapter.xsd)
对于此示例,我们将使用以下XML架构:
<?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>
Run Code Online (Sandbox Code Playgroud)
字符串转换
我们需要定义一个类来进行特殊的String处理.对于此用例,我们希望在XML文档中将空字段/属性值视为空字符串(""):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
绑定文件(attributeAdapterBinding.xml)
我们需要使用JAXB绑定文件来自定义类生成.下面的绑定文件将允许我们利用上面定义的StringConverter类:
<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>
Run Code Online (Sandbox Code Playgroud)
XJC电话
我们将按如下方式拨打XJC电话:
xjc -d out -b attributeAdapterBinding.xml attributeAdapter.xsd
Run Code Online (Sandbox Code Playgroud)
域模型(根)
我们在绑定文件中自定义的字段/属性将使用@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;
}
}
Run Code Online (Sandbox Code Playgroud)
XmlAdapter(Adapter1)
生成的XmlAdapter类将如下所示.请注意它如何利用我们的StringConverter类:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
演示
现在,如果我们运行以下演示代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
产量
我们将获得所需的输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://www.example.com/adapter" foo="" bar=""/>
Run Code Online (Sandbox Code Playgroud)
更新(替代绑定文件)
或者,如果您希望将适配器应用于所有类型的属性,xsd:string那么您可以使用看起来像的绑定文件;
<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>
Run Code Online (Sandbox Code Playgroud)
从Java对象开始
对于映射为的字段/属性@XmlAttribute,JAXB实现(Metro,MOXy,JaxMe等)将封送空字符串("")值为property="".您可以使用an XmlAdapter将空值公开为空字符串以获得所需的行为:
NullStringAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class NullStringAdapter extends XmlAdapter<String, String> {
@Override
public String unmarshal(String v) throws Exception {
if("".equals(v)) {
return null;
}
return v;
}
@Override
public String marshal(String v) throws Exception {
if(null == v) {
return "";
}
return v;
}
}
Run Code Online (Sandbox Code Playgroud)
根
以下是在域模型中指定适配器的方法.可以在许多属性上使用相同的适配器:
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Root {
private String foo;
private String bar;
@XmlAttribute
@XmlJavaTypeAdapter(NullStringAdapter.class)
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
@XmlAttribute
@XmlJavaTypeAdapter(NullStringAdapter.class)
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
Run Code Online (Sandbox Code Playgroud)
演示
您可以通过运行以下演示代码来演示该概念:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
产量
以下是演示代码输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root bar="" foo=""/>
Run Code Online (Sandbox Code Playgroud)
有关JAXB的XmlAdapter的更多信息,请参阅:
| 归档时间: |
|
| 查看次数: |
7725 次 |
| 最近记录: |