rommel
rommel

Reputation: 61

XML adding the same element as a child (Getting HIERARCHY_REQUEST_ERR)

How do I add the same element as a child. I want something like this:

<family>
  <parent name = "P1">
    <child name = "P1C1">
        <child name = "P1C1C1"/>
        <child name = "P1C1C2"/>
    </child>
    <child name = "P1C2"/>
    <child name = "P1C3">
      <child name = "P1C3C1"/>
    </child>
  </parent>
  <parent name = "P2">
    <child name = "P2C1">
        <child name = "P2C1C1"/>
    </child>
    <child name = "P2C2">
        <child name = "P2C2C1"/>
    </child>
  </parent>
</family>

If I try to create a child element and add another child to it I get:

HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.

How can we generate the above XML tree?

Also see the bigger picture for the solution I am building: Generate XML mapping of a recursive directory search

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


public class ChildofChildXML {

    public static void main(String[] args) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = factory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
            Element root = doc.createElement("family");   
            doc.appendChild(root);   

            Element parent = doc.createElement("parent");
            parent.setAttribute("name","P1");
            root.appendChild(parent);

            Element childElement = doc.createElement("child");
            childElement.setAttribute("name","P1C1");
            parent.appendChild(childElement);


            Element childElement2 = doc.createElement("child"); //Works
            childElement2.setAttribute("name","P1C1C1");
            childElement.appendChild(childElement2);

            /*
            childElement = doc.createElement("child");
            childElement.setAttribute("name","P1C1C1");

            // Not allowed - HIERARCHY_REQUEST_ERR: 
            childElement.appendChild(childElement); 
            */

            childElement = doc.createElement("child");
            childElement.setAttribute("name","P1C2");
            parent.appendChild(childElement);

            TransformerFactory tranFactory = TransformerFactory.newInstance();
            Transformer aTransformer = tranFactory.newTransformer();
            aTransformer.setOutputProperty("indent", "yes");

            Source src = new DOMSource(doc);
            Result dest = new StreamResult(System.out);
            aTransformer.transform(src, dest);  
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Now the code needs to be merged with a recursive 'expand archive' call and that is where I am wondering how to add child of child as I need to apply the solution to recursion - where I am expanding a top level archive file using java.util.zip. The here is equivalent of the folder that contains the top level archive that being the parent and subsequent nodes are equivalent of the contents of the archives recursively. So an ear could have a war or a jar. The war could have jsp under it and WEB-INF/lib/x.jar and WEB-INF/lib/x.jar needs to be expanded again and so on and this child --> child --> child relationship is to be built up from the parent.

Upvotes: 1

Views: 16920

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500695

This is the problem:

childElement.appendChild(childElement);

You're trying to add a child element to itself. You can't do that. It doesn't make any sense to do that... an element can't be a child of itself. How would you expect that to be represented in the final XML?

If you change that code to

parent.appendChild(childElement);

or

childElement2.appendChild(childElement);

then it's fine.

Upvotes: 4

Andreas Dolk
Andreas Dolk

Reputation: 114787

You can add a <child> node as a child to <parent> and other <child> nodes. It is not allowed to add it to <family> or to the document directly. (rough guess - I'd need to see the schema or DTD)


Second - if you create elements for a document, always use this pattern:

Element element = doc.createElement("child");

Upvotes: 1

Related Questions