3

Hi im looking for a solution to append nodes from java into an existing xml file. What i got is an xml file like this

<data>
<people>
    <person>
        <firstName>Frank</firstName>
        <lastName>Erb</lastName>
        <access>true</access>
        <images>
            <img>hm001.jpg</img>
        </images>
    </person>
    <person>
        <firstName>Hans</firstName>
        <lastName>Mustermann</lastName>
        <access>true</access>
        <images>
            <img>hm001.jpg</img>
        </images>
    </person>
    <person>
        <firstName>Thomas</firstName>
        <lastName>Tester</lastName>
        <access>false</access>
        <images>
            <img>tt001.jpg</img>
        </images>
    </person>
</people>
 </data>

what i whant to add is a person node with its elements inside the people element. My big problem is the data node which is root node. If it would be the Person node as root I could solve it. But I can't manage to get the person nodes under the people node.

           <person>
        <firstName>Tom</firstName>
        <lastName>Hanks</lastName>
        <access>false</access>
        <images>
            <img>tt001.jpg</img>
        </images>
    </person>

thanks for your help!

my java code looks as far like this

Element root = document.getDocumentElement();


// Root Element
Element rootElement = document.getDocumentElement();

Collection<Server> svr = new ArrayList<Server>();
svr.add(new Server());

for (Server i : svr) {
    // server elements

    Element server = document.createElement("people");
    rootElement.appendChild(server);
    //rootElement.appendChild(server);

    Element name = document.createElement("person");
    server.appendChild(name);

    Element firstName = document.createElement("firstName");
    firstName.appendChild(document.createTextNode(i.getFirstName()));
    server.appendChild(firstName);
    name.appendChild(firstName);

    Element port = document.createElement("lastName");
    port.appendChild(document.createTextNode(i.getLastName()));
    server.appendChild(port); 
    name.appendChild(port);

    Element access = document.createElement("access");
    access.appendChild(document.createTextNode(i.getAccess()));
    server.appendChild(access); 
    name.appendChild(access);

    String imageName = Main.randomImgNr+"";
    Element images = document.createElement("images");
    //images.appendChild(document.createTextNode(i.getAccess()));
    Element img = document.createElement("img");
    img.appendChild(document.createTextNode(imageName));//i.getImage()));
    images.appendChild(img);            

    server.appendChild(images);
    name.appendChild(images);
    root.appendChild(server);
1
  • 1
    Tried using JAXB? It's pretty neat. Commented Jan 20, 2014 at 17:11

4 Answers 4

7

Without a library you can do something like this:

Element dataTag = doc.getDocumentElement();
Element peopleTag =  (Element) dataTag.getElementsByTagName("people").item(0);

Element newPerson = doc.createElement("person");

Element firstName = doc.createElement("firstName");
firstName.setTextContent("Tom");

Element lastName = doc.createElement("lastName");
lastName.setTextContent("Hanks");

newPerson.appendChild(firstName);
newPerson.appendChild(lastName);

peopleTag.appendChild(newPerson);

Which results:

...
        <person>
            <firstName>Thomas</firstName>
            <lastName>Tester</lastName>
            <access>false</access>
            <images>
                <img>tt001.jpg</img>
            </images>
        </person>
        <person>
            <firstName>Tom</firstName>
            <lastName>Hanks</lastName>
        </person>
    </people>
</data>
Sign up to request clarification or add additional context in comments.

1 Comment

Is there any possibility to get the new nodes into the right formatting? Whenever i try to add those nodes, they stuck on the left side. Thanks for the help in advance.
1

This is very easy with JOOX library, examples:

// Parse the document from a file
Document document = $(xmlFile).document();

// Find the order at index 4 and add an element "paid"
$(document).find("people").children().eq(4).append("<paid>true</paid>");

// Find those orders that are paid and flag them as "settled"
$(document).find("people").children().find("paid").after("<settled>true</settled>");

2 Comments

Isn't it possible to do this without using an library or wrapper?
It is much easier with library.
0

Follow this general approach:

public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    try {
        db = dbf.newDocumentBuilder();
        Document doc = db.parse("input.xml");
        NodeList people = doc.getElementsByTagName("people");
        people.item(0)
                .appendChild(
                        createPersonElement(doc, "Tom", "Hanks", true,
                                "tt001.jpg"));
        System.out.println(nodeToString(doc));
    } catch (SAXException e) {
        // handle SAXException
    } catch (IOException e) {
        // handle IOException
    } catch (TransformerException e) {
        // handle TransformerException
    } catch (ParserConfigurationException e1) {
        // handle ParserConfigurationException
    }
}

private static Element createPersonElement(Document doc, String firstName,
        String lastName, Boolean access, String image) {
    Element el = doc.createElement("person");
    el.appendChild(createPersonDetailElement(doc, "firstName", firstName));
    el.appendChild(createPersonDetailElement(doc, "lastName", lastName));
    el.appendChild(createPersonDetailElement(doc, "access",
            access.toString()));
    Element images = doc.createElement("images");
    images.appendChild(createPersonDetailElement(doc, "img", image));
    el.appendChild(images);
    return el;
}

private static Element createPersonDetailElement(Document doc, String name,
        String value) {
    Element el = doc.createElement(name);
    el.appendChild(doc.createTextNode(value));
    return el;
}

This uses the following helper method to print the results:

private static String nodeToString(Node node) throws TransformerException {
    StringWriter buf = new StringWriter();
    Transformer xform = TransformerFactory.newInstance().newTransformer();
    xform.transform(new DOMSource(node), new StreamResult(buf));
    return buf.toString();
}

This could be modified to update the original file instead.

Comments

-1
public static void main(String[] args) throws ParserConfigurationException, IOException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db;
    db = null;
    try {
        db = dbf.newDocumentBuilder();
        Document doc = db.parse("input.xml");
        NodeList people = doc.getElementsByTagName("people");
        people.item(0).appendChild(createPersonElement(doc, "Tom", "Hanks", true, "tt001.jpg"));
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        DOMSource source = new DOMSource(doc);
        StreamResult console = new StreamResult(System.out);//for Console print
        transformer.transform(source, console);
        StreamResult file = new StreamResult(new File("input.xml"));
        transformer.transform(source, file);
    } catch (SAXException | IOException | TransformerException | ParserConfigurationException e) {
        System.out.println(e);
    }
}

private static Element createPersonElement(Document doc, String firstName,
        String lastName, Boolean access, String image) {
    Element el = doc.createElement("person");
    el.appendChild(createPersonDetailElement(doc, "firstName", firstName));
    el.appendChild(createPersonDetailElement(doc, "lastName", lastName));
    el.appendChild(createPersonDetailElement(doc, "access",
            access.toString()));
    Element images = doc.createElement("images");
    images.appendChild(createPersonDetailElement(doc, "img", image));
    el.appendChild(images);
    return el;
}

private static Element createPersonDetailElement(Document doc, String name,
        String value) {
    Element el = doc.createElement(name);
    el.appendChild(doc.createTextNode(value));
    return el;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.