Search code examples
javaxmlxom

Insert additional parent XML element using XOM


With the following XML:

<parent>
    <child>Stuff</child>
    <child>Stuff</child>
</parent>

Using XPath I query the child elements, and based on some conditions I want to append an extra parent level above some of them:

<parent>
    <extraParent>
        <child>Stuff</child>
    </extraParent>
    <child>Stuff</child>
</parent>

What's the best way to do this?

I was thinking something along the following lines:

Nodes childNodes = parent.query("child");
for (int i = 0; i < childNodes.size(); i++) {
    Element currentChild = (Element) childNodes.get(i);
    if (someCondition) {
        ParentNode parent = currentChild.getParent();
        currentChild.detach();
        Element extraParent = new Element("extraParent");
        extraParent.appendChild(currentChild);
        parent.appendChild(extraParent);
    }
}

But I want to preserve the order. Possibly this could be done using parent.insertChild(child, position)?

Edit: I think the following works, but I'm curious if anyone has a better way:

Elements childElements = parent.getChildElements();
for (int i = 0; i < childElements.size(); i++) {
    Element currentChild = childElements.get(i);
    if (someCondition) {
        ParentNode parent = currentChild.getParent();
        currentChild.detach();
        Element extraParent = new Element("extraParent");
        extraParent.appendChild(currentChild);
        parent.insertChild(extraParent,i);
    }
}

Edit 2: This is possibly better, as it allows you to have other elements mixed in with the child elements that you aren't interested in:

Nodes childNodes = parent.query("child");
for (int i = 0; i < childNodes.size(); i++) {
    Element currentChild = (Element) childNodes.get(i);
    if (someCondition) {
        ParentNode parent = currentChild.getParent();
        int currentIndex = parent.indexOf(currentChild);
        currentChild.detach();
        Element extraParent = new Element("extraParent");
        extraParent.appendChild(currentChild);
        parent.insertChild(extraParent,currentIndex);
    }
}

Solution

  • This seems to work adequately:

    Nodes childNodes = parent.query("child");
    for (int i = 0; i < childNodes.size(); i++) {
        Element currentChild = (Element) childNodes.get(i);
        if (someCondition) {
            ParentNode parent = currentChild.getParent();
            int currentIndex = parent.indexOf(currentChild);
            currentChild.detach();
            Element extraParent = new Element("extraParent");
            extraParent.appendChild(currentChild);
            parent.insertChild(extraParent,currentIndex);
        }
    }