我正在使用JAXB将java对象编组为XML。我面临的问题是,并非所有java对象实例的成员变量都需要编组XML。例如,我的完整XML文档应该看起来像 -
<Disk>
<status>attached</status>
<size>10000000000</size>
<freeSpace>25600000<freeSpace>
<id>MI45563PO</id>
</Disk>
但是在更新的情况下,只有选定的属性会发生变化,只有更改过的属性应该是编组XML的一部分。就像'status'属性可以改为'detached'一样,在这种情况下,编组的XML应该如下所示 -
<Disk>
<status>detached</status>
</Disk>
或者,在'freeSpace'的情况下,XML应该看起来像 -
<Disk>
<freeSpace>20000000<freeSpace>
</Disk>
我的问题:将未更改的字段定义为null(因此将所有基本类型定义为包装类变量,如Integer,Boolean等)是获得所需结果的唯一解决方案?或者,在JAXB中是否有任何方法可以指定所选字段,这些字段应该在结果XML中进行编组,其余字段应该被忽略。
请注意,需要忽略且需要包含的字段集在任何时间点都不固定。
答案 0 :(得分:2)
如果您想要查看一个类的一些视图,则应为每个视图创建decorator类。 示例源代码:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;
public class Program {
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Disk.class,
OnlyDiskStatusDecorator.class, OnlyDiskFreeSpaceDecorator.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
Disk disk = new Disk();
disk.setStatus("attached");
disk.setSize(10000000000L);
disk.setFreeSpace(25600000L);
disk.setId("MI45563PO");
m.marshal(disk, System.out);
m.marshal(new OnlyDiskStatusDecorator(disk), System.out);
m.marshal(new OnlyDiskFreeSpaceDecorator(disk), System.out);
}
}
@XmlRootElement
class Disk {
private String status;
private long size;
private long freeSpace;
private String id;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public long getFreeSpace() {
return freeSpace;
}
public void setFreeSpace(long freeSpace) {
this.freeSpace = freeSpace;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "Disk [status=" + status + ", size=" + size + ", freeSpace="
+ freeSpace + ", id=" + id + "]";
}
}
@XmlRootElement(name = "Disk")
class OnlyDiskStatusDecorator {
private Disk disk;
public OnlyDiskStatusDecorator() {
}
public OnlyDiskStatusDecorator(Disk disk) {
this.disk = disk;
}
public String getStatus() {
return disk.getStatus();
}
public void setStatus(String status) {
}
}
@XmlRootElement(name = "Disk")
class OnlyDiskFreeSpaceDecorator {
private Disk disk;
public OnlyDiskFreeSpaceDecorator() {
}
public OnlyDiskFreeSpaceDecorator(Disk disk) {
this.disk = disk;
}
public long getFreeSpace() {
return disk.getFreeSpace();
}
public void setFreeSpace(long freeSpace) {
}
}
以上示例打印:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<disk>
<freeSpace>25600000</freeSpace>
<id>MI45563PO</id>
<size>10000000000</size>
<status>attached</status>
</disk>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Disk>
<status>attached</status>
</Disk>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Disk>
<freeSpace>25600000</freeSpace>
</Disk>
我为两个类视图创建了两个装饰器。第一个装饰器用于状态更新,第二个用于更新freeSpace值。你也可以为特定的序列化创建XmlAdapter的实现,但我认为它有点复杂。
答案 1 :(得分:0)
您是否曾使用XSL Transformation对XML&amp;然后使用JAXB?
我处于类似的情况,我有大约3000个JAXB DTO!我把它们减少到一个可管理的数字,28。
查看w3schools的tutorial。