Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

As the title suggests, I am trying to add elements to an xml doc using a for loop. I have an ArrayList of strings called names that I wish to iterate through, and for each name create a <user> element with attribute name and with a child <record> that has the attributes id, time, date, and project.

Unfortunately, if you scroll down in the code below to the createDoc() method, when I try to call doc.appendChild(user), I get the following error:

Exception in thread "main" org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted. 
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(Unknown Source)
at org.apache.xerces.dom.NodeImpl.appendChild(Unknown Source)
at test.XMLwriter.createDoc(XMLwriter.java:131)
at test.XMLwriter.<init>(XMLwriter.java:116)
at test.TestRunner.main(TestRunner.java:33)

I have looked at a few questions on stackoverflow that have the same error, but they all seem to have occurred under completely different circumstances with respect to mine. My best guess is that this error has to do with the fact that I am trying to create too many parent elements at the same hierarchical level, but I am not sure and I have almost no experience with xml at all.

Here is the code:

public class XMLwriter {
private ArrayList<String> names;
private Document doc;
private Random rand;
private ArrayList<Element> users;

public XMLwriter() throws ParserConfigurationException, TransformerException{

    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    doc = docBuilder.newDocument();

    rand = new Random();
    users = new ArrayList<Element>();
    names = new ArrayList<String>();

    names.add("Ralph Wiggum");names.add("Mr. Hanky");names.add("Bulbasaur");
    names.add("Tyroil Smoochie Wallace");names.add("Scooby Doo");names.add("Neville Longbottom");
    names.add("Jabba the Hutt");names.add("Silky Johnson");names.add("Master Chief");
    names.add("Frodo Baggins");names.add("Clayton Bigsby");names.add("John Snow");
    names.add("Eric Cartman");names.add("Leoz Maxwell Jilliumz");names.add("Aslan");

    createDoc();
    generateFile();

}

public void createDoc(){
    for(int k = 0; k < names.size(); k++)
    {
        users.add(doc.createElement("user"));
    }
    for (int x = 0; x < names.size(); x++){

        //create the elements
        Element record = doc.createElement("record");
        users.get(x).appendChild(record);
        doc.appendChild(users.get(x));//The line that is throwing the error

        //create the attributes
        Attr name = doc.createAttribute("name");
        Attr date = doc.createAttribute("date");
        Attr project = doc.createAttribute("project");
        Attr time = doc.createAttribute("time");
        Attr id = doc.createAttribute("id");

        //give all of the attributes values
        name.setValue(names.get(x));
        date.setValue(new Date().toString());
        project.setValue("Project" + (rand.nextDouble() * 1000));
        time.setValue("" + rand.nextInt(10));
        id.setValue("" + (rand.nextDouble() * 10000));

        //assign the attributes to the elements
        users.get(x).setAttributeNode(name);
        record.setAttributeNode(date);
        record.setAttributeNode(project);
        record.setAttributeNode(time);
        record.setAttributeNode(id);


    }
}

public void generateFile() throws TransformerException{
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(new File("C:\\Users\\sweidenkopf\\workspace\\test\\testxml.xml"));

    // Output to console for testing
    // StreamResult result = new StreamResult(System.out);
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    transformer.transform(source, result);
}

}

I wrote this code as sort of a proof of concept because I will eventually have to actually perform a similar operation, where I will have a list of objects, each of which I must add to an xml file by separating the object out into its constituent parts with get methods.

Can anyone help me resolve this error?

share|improve this question
add comment

1 Answer

up vote 0 down vote accepted

I discovered the answer to this problem. Here is how:

I created another hierarchical layer called <userList> Each time the for loop iterated, I made the newly created <user> a child of <userList>.

Finally, beyond the scope of the for loop, I made the <userList> a child of the xml document as a whole.

Here is the new code for those interested. You can read the comments in the createDoc() method to help clarify what I explained above:

public class XMLwriter {
private ArrayList<String> names;
private Document doc;
private Random rand;
private ArrayList<Element> users;

public XMLwriter() throws ParserConfigurationException, TransformerException{

    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    doc = docBuilder.newDocument();

    rand = new Random();
    users = new ArrayList<Element>();
    names = new ArrayList<String>();

    names.add("Ralph Wiggum");names.add("Mr. Hanky");names.add("Bulbasaur");
    names.add("Tyroil Smoochie Wallace");names.add("Scooby Doo");names.add("Neville Longbottom");
    names.add("Jabba the Hutt");names.add("Silky Johnson");names.add("Master Chief");
    names.add("Frodo Baggins");names.add("Clayton Bigsby");names.add("John Snow");
    names.add("Eric Cartman");names.add("Leoz Maxwell Jilliumz");names.add("Aslan");

    createDoc();
    generateFile();

}

public void createDoc(){
    Element userList = doc.createElement("userList");//here, I create a new, over-arching element.
    for(int k = 0; k < names.size(); k++)
    {
        users.add(doc.createElement("user"));
    }
    for (int x = 0; x < 2; x++){

        //create the elements
        Element record = doc.createElement("record");
        users.get(x).appendChild(record);
        userList.appendChild(users.get(x));//I make each of the <user> elements a child of the over-arching element
        //The line that was throwing the error

        //create the attributes
        Attr name = doc.createAttribute("name");
        Attr date = doc.createAttribute("date");
        Attr project = doc.createAttribute("project");
        Attr time = doc.createAttribute("time");
        Attr id = doc.createAttribute("id");

        //give all of the attributes values
        name.setValue(names.get(x));
        date.setValue(new Date().toString());
        project.setValue("Project" + (rand.nextDouble() * 1000));
        time.setValue("" + rand.nextInt(10));
        id.setValue("" + (rand.nextDouble() * 10000));

        //assign the attributes to the elements
        users.get(x).setAttributeNode(name);
        record.setAttributeNode(date);
        record.setAttributeNode(project);
        record.setAttributeNode(time);
        record.setAttributeNode(id);


    }
    doc.appendChild(userList);//note how I append this child outside of the for loop
}

public void generateFile() throws TransformerException{
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(new File("C:\\Users\\sweidenkopf\\workspace\\test\\testxml.xml"));

    // Output to console for testing
    // StreamResult result = new StreamResult(System.out);
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    transformer.transform(source, result);
}

}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.