我对JAXB很陌生,所以我不确定它是否可能是我想做的。
我有一个XML文件,我基本上为我的程序配置了运行参数。某些配置共享大量相同的参数,只有1或2不同。所以我的XML目前看起来像这样:
<Parameters id="1">
<Attribute1>value1<Attribute1>
<Attribute2>value2<Attribute2>
<Attribute3>value3<Attribute3>
<Attribute4>value4<Attribute4>
<Attribute5>value5<Attribute5>
</Parameters>
<Parameters id="2">
<Attribute1>value1<Attribute1>
<Attribute2>value2<Attribute2>
<Attribute3>value3<Attribute3>
<Attribute4>otherValue4<Attribute4>
<Attribute5>otherValue5<Attribute5>
</Parameters>
我正在寻找一种方法来减少冗余,因此我有一个基本配置,然后是扩展,在扩展中我只需要配置不同的参数。
<Parameters id="1">
<Attribute1>value1<Attribute1>
<Attribute2>value2<Attribute2>
<Attribute3>value3<Attribute3>
</Parameters>
<Parameters id="2" parent="1">
<Attribute4>value4<Attribute4>
<Attribute5>value5<Attribute5>
</Parameters>
<Parameters id="3" parent="1">
<Attribute4>otherValue4<Attribute4>
<Attribute5>otherValue5<Attribute5>
</Parameters>
值得一提的是,父节点的属性集对于不同的配置组是不固定的,即在其他情况下,Attribute1可能是正在改变的属性。这对JAXB来说是否可能?
我想我对问题场景的初步描述有点不清楚/遗漏了一些细节。
我的参数设置是同一根节点下的一个xml文件中的所有单个节点。我正在使用XPATH检索单个参数节点并将此节点解组为Parameters对象。
到目前为止一切顺利,但我现在要做的是通过使用某种继承来重构我的xml以减少冗余。例如,当加载id =“2”的节点时,我希望我的Parameters对象继承id =“1”的节点的值。
我通过两个简单的步骤解决了这个问题。在第一步中,我只是从XML节点加载对象。然后我检查节点是否有一个指定的parentId。如果是这种情况,我还会加载父对象,并将fiedl值复制到子对象(如果尚未设置)。
public static Parameters createParams(String id){
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(new File("src/test.xml"));
XPath xPath = XPathFactory.newInstance().newXPath();
JAXBContext jc = JAXBContext.newInstance(Parameters.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Node n = (Node) xPath.compile("/config/Parameters[@id='"+id+"']").evaluate(xmlDocument, XPathConstants.NODE);
Parameters p = (Parameters) unmarshaller.unmarshal(n);
if(p.parentId != null)
p.loadValuesFromParent(createParams(p.parentId));
return p;
}
public void loadValuesFromParent(Parameters parent) throws IllegalArgumentException, IllegalAccessException{
for (Field field : Parameters.class.getDeclaredFields()) {
if(field.get(this)==null){
field.set(this,field.get(parent));
}
}
}
答案 0 :(得分:0)
根据我的评论,这可以通过任何简单的pojo来实现,除非问题中缺少某些东西,这是特别的。
使用main。
示例pojoimport javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameters {
@XmlAttribute
private String id;
@XmlAttribute
private String parent;
@XmlElement(name = "Attribute1")
private String attribute1;
@XmlElement(name = "Attribute2")
private String attribute2;
@XmlElement(name = "Attribute3")
private String attribute3;
@XmlElement(name = "Attribute4")
private String attribute4;
@XmlElement(name = "Attribute5")
private String attribute5;
public static void main(String[] args) throws Exception{
JAXBContext jc = JAXBContext.newInstance(Parameters.class);
Marshaller marrshaller = jc.createMarshaller();
marrshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
Parameters p1 = new Parameters();
p1.id="1";
p1.attribute1="value1";
p1.attribute2="value2";
p1.attribute3="value3";
marrshaller.marshal(p1, System.out);
p1 = new Parameters();
p1.id="2";
p1.parent="1";
p1.attribute4="value4";
p1.attribute5="value5";
marrshaller.marshal(p1, System.out);
p1 = new Parameters();
p1.id="3";
p1.parent="1";
p1.attribute4="Othervalue4";
p1.attribute5="othervalue5";
marrshaller.marshal(p1, System.out);
}
}
三个xml输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parameters id="1">
<Attribute1>value1</Attribute1>
<Attribute2>value2</Attribute2>
<Attribute3>value3</Attribute3>
</parameters>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parameters parent="1" id="2">
<Attribute4>value4</Attribute4>
<Attribute5>value5</Attribute5>
</parameters>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parameters parent="1" id="3">
<Attribute4>Othervalue4</Attribute4>
<Attribute5>othervalue5</Attribute5>
</parameters>