基于XML-Nodes

时间:2017-11-08 08:34:22

标签: java xml jaxb

我对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));
        }
    } 
}

1 个答案:

答案 0 :(得分:0)

根据我的评论,这可以通过任何简单的pojo来实现,除非问题中缺少某些东西,这是特别的。

使用main。

示例pojo
import 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>