我有两个XML文件
tree.xml
<tree>
<xi:include href="fruit.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:fallback>
<fruit/>
</xi:fallback>
</xi:include>
</tree>
fruit.xml
<fruit>
...
</fruit>
我继承了解组文件的代码,它返回一个java对象。我现在需要将单个java对象编组回两个文件。我意识到还有其他解决方案(即使用两个对象而不是一个,这是一个选项)但我需要知道是否可以编组单个对象并维护xi:include(或重新引入它)并导出为两个(或者更多)xml文件。
这甚至可能吗?如果有任何提示/想法?
由于
更新
我一直在研究这个问题(我在询问之前进行了研究)。我确实找到了这个教程http://tutorial.waycoolsearch.com/java/jaxb2.php似乎有我的答案,但是当我把文件编组时它需要两个并制作一个。
答案 0 :(得分:3)
下面我将演示如何使用XmlAdapter
来支持此用例的编组和解组。
XmlAdapter(IncludeFruitAdapter)
XmlAdapter
可以用于此用例。
import java.io.File;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class IncludeFruitAdapter extends XmlAdapter<IncludeFruitAdapter.Include, Fruit> {
private JAXBContext jc;
private String href = "fruit.xml";
public IncludeFruitAdapter() {
try {
jc = JAXBContext.newInstance(Fruit.class);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public static class Include {
@XmlAttribute
public String href;
@XmlElement(namespace="http://www.w3.org/2001/XInclude")
public Fallback fallback;
}
public static class Fallback {
@XmlElementRef
public Fruit value;
}
@Override
public Include marshal(Fruit fruit) throws Exception {
File xml = new File(href);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(fruit, xml);
Include include = new Include();
include.href = href;
include.fallback = new Fallback();
include.fallback.value = new Fruit();
return include;
}
@Override
public Fruit unmarshal(Include include) throws Exception {
File xml = new File(include.href);
Unmarshaller unmarshaller = jc.createUnmarshaller();
try {
return (Fruit) unmarshaller.unmarshal(xml);
} catch(Exception e) {
return include.fallback.value;
}
}
}
<强>树强>
@XmlJavaTypeAdapter
用于引用XmlAdapter
。
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Tree {
@XmlJavaTypeAdapter(IncludeFruitAdapter.class)
@XmlElement(name="include", namespace="http://www.w3.org/2001/XInclude")
private Fruit fruit;
}
<强>水果强>
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Fruit {
private String name;
}
<强>演示强>
下面是一些可以运行的演示代码,以证明一切正常:
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Tree.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input.xml");
Tree tree = (Tree) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(tree, System.out);
}
}
答案 1 :(得分:0)
我找到了答案,至少是一个解决方法。我想这可能就是这样做的方法。
我希望JAXB有某种方法来定义一个对象的一部分作为编组的包含,但我找不到任何东西。
注意:我有一个额外的黑客攻击,我将在下面解释,我想你可以在没有但我无法工作的情况下完成它,并且在其他人需要这样做的情况下,至少他们会知道。< / p>
流程如下。
我很快会用代码更新。
还有其他方法可以解决这个问题吗?
谢谢, 特拉维斯