2

My source code needs to append/add new tags between some existing tags to XML document what I have on my hard-disk. I am seriously confused what kind of parser do I need to use to complete this task.

XML document what I have looks similar to:

<school>
<teacher>
<name>XXXXX</name>
<gender>XXXX</gender>
</teacher>
</school>

Need this XML document to be:

 <school>
<teacher>
<name>XXXXX</name>
<gender>XXXX</gender>
</teacher>
<!--need to append student tag-->
<student>
<name>XXXXXX</name>
<gender>XXXXX</name>
</student>
</school>

So, please help me in choosing efficient xmlparser in achieving this job.also, I appreciate if you can show me sample source code to achieve this task.

Thanks in advance..

Rakesh
  • 23
  • 1
  • 3

2 Answers2

2

If I'm understanding the question correctly, I'm assuming you're trying to take an xml document that contains teachers, and for those teachers, you'd like to add their corresponding students.

I'd suggest using a DOM parser (link at the bottom for reference).

I've created some code that will allow you to take an XML file with teacher information, and generate a new one with your desired result.

I used an excessive amount of comments for your convenience!

package com.yourpackage.model;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class addStudentsXml {
    public static void main(String[] args) throws Exception {

        //Create the DocumentBuilderFactory
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

        //Parse your XML file
        Document document = documentBuilder.parse("yourFileName.xml"); //Insert your file name here

        //Declare the school that you wish to populate
        School school = new School();

        //Create the list of teachers
        List<Teacher> teachers = new ArrayList<Teacher>();

        //Create the list of nodes from the document
        NodeList nodeList = document.getDocumentElement().getChildNodes();

        //Populate the teacher list with all of the teachers in the XML document
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node instanceof Element) {
                Teacher newTeacher = new Teacher();
                newTeacher.name = node.getAttributes().getNamedItem("name").getNodeValue();

                NodeList childNodes = node.getChildNodes();
                for (int j = 0; j < childNodes.getLength(); j++) {
                    Node cNode = childNodes.item(j);

                    if (cNode instanceof Element) {
                        String content = cNode.getLastChild().getTextContent().trim();

                        if(cNode.getNodeName().equals("name")) {
                            newTeacher.name = content;
                        } else if(cNode.getNodeName().equals("gender")) {
                            newTeacher.gender = content;
                        }
                    }
                }
                //Add new teachers to the teacher list
                teachers.add(newTeacher);
            }
        }

        //Add your teachers to your school
        school.setTeachers(teachers);

        //Create the list of students
        List<Student> students = new ArrayList<Student>();

        //Populate your students here depending upon how your data is feeding them in

        //Add your students to your school
        school.setStudents(students);

        //Now we will start to create the new xml document to be exported
        Document newDoc = documentBuilder.newDocument();

        //Create the root of the doucment
        Element root = newDoc.getDocumentElement();

        //Create the school element
        Element newSchool = newDoc.createElement("school");

        //Add the school to the root of the document
        root.appendChild(newSchool);

        //For all of the teachers in the teacher list, add their corresponding students
        for (Teacher teacher : teachers) {
            //Create the teacher element
            Element newTeacher = newDoc.createElement("teacher");

            //Add the teacher's name
            Element teacherName = newDoc.createElement("name");
            teacherName.appendChild(newDoc.createTextNode(teacher.getName()));
            newTeacher.appendChild(teacherName);

            //Add the teacher's gender
            Element teacherGender = newDoc.createElement("gender");
            teacherGender.appendChild(newDoc.createTextNode(teacher.getGender()));
            newTeacher.appendChild(teacherGender);

            //Add the teacher to the school
            newSchool.appendChild(newTeacher);
            for (Student student : students) {
                if (student.getTeacherName().trim().equals(teacher.getName().trim())) {
                    //Create the student element
                    Element newStudent = newDoc.createElement("student");

                    //Add the student's name
                    Element studentName = newDoc.createElement("name");
                    studentName.appendChild(newDoc.createTextNode(student.getName()));
                    newStudent.appendChild(studentName);

                    //Add the student's gender
                    Element studentGender = newDoc.createElement("gender");
                    studentGender.appendChild(newDoc.createTextNode(student.getGender()));
                    newStudent.appendChild(studentGender);

                    //Add the student to the school
                    newSchool.appendChild(newStudent);
                }       
            }
        }

        //Create the transformerFactory, transformer, and the result to be saved to a new file "schoolinfo.xml"
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(newDoc);
        StreamResult result = new StreamResult(new File("C://schoolinfo.xml"));

        transformer.transform(source, result);

        System.out.println("File saved!");

    }

    public static class School {
        private List<Teacher> teachers;
        private List<Student> students;

        public void setTeachers(List<Teacher> teachers) {
            this.teachers = teachers;
        }

        public void setStudents(List<Student> students) {
            this.students = students;
        }

        public List<Teacher> getTeachers() {
            return teachers;
        }

        public List<Student> getStudents() {
            return students;
        }
    }

    public static class Teacher {
        private String name = "";
        private String gender =  "";

        public String getName() {
            return name;
        }
        public String getGender() {
            return gender;
        }
    }

    public static class Student {
        private String studentName = "";
        private String studentGender = "";
        private String teacherName = "";

        public String getName() {
            return studentName;
        }
        public String getGender() {
            return studentGender;
        }
        public String getTeacherName() {
            return teacherName;
        }
    }
}

This should read in your XML file (you'll have to replace the file name with your actual file name) and populate a list of teachers. As far as student information goes, you'll have to populate that list from wherever you are retrieving that data from.

Once that data is available and stored properly, a new document will be created and XML should be appended to that document in the form that you desired. This document will be stored to your C: drive, but you can change that path to store it wherever you'd like.

I used these links as references:
MKYong (Exporting an XML file): here
Stackoverflow (Appending nodes): here
Java Code Geeks (DOM Parsers): here

Let me know if there is anything in my solution that needs clarification, I'm new to stackoverflow!

Community
  • 1
  • 1
Kyle Stoflet
  • 1,194
  • 3
  • 16
  • 27
2

XOM is the simplest XML system for Java. You can avoid quite a lot of clutter by manipulating the XOM tree itself.

public void test() throws ParsingException, ValidityException, IOException {
    String xml = "<school><teacher><name>XXXXX</name><gender>XXXX</gender></teacher></school>";
    String add = "<student><name>XXXXXX</name><gender>XXXXX</gender></student>";
    Builder parser = new Builder();
    // Parse them.
    Document school = parser.build(new ByteArrayInputStream(xml.getBytes()));
    Document student = parser.build(new ByteArrayInputStream(add.getBytes()));
    // Manipulate - remember to copy.
    school.getRootElement().appendChild(student.getRootElement().copy());
    // To XML.
    System.out.println(school.getRootElement().toXML());
}

prints:

<school><teacher><name>XXXXX</name><gender>XXXX</gender></teacher><student><name>XXXXXX</name><gender>XXXXX</gender></student></school>

i.e.

    <school>
        <teacher>
            <name>XXXXX</name>
            <gender>XXXX</gender>
        </teacher>
        <student>
            <name>XXXXXX</name>
            <gender>XXXXX</gender>
        </student>
    </school>

For significant projects however, it would probably be a better solution to marshal the XML into objects, manipulate the objects and unmarshal them back to xml (as suggested by @KyleStoflet).

Alternatively - you could use brute-force and manipulate the strings directly. This is deeply frowned-upon.

public void test() {
    String xml = "<school><teacher><name>XXXXX</name><gender>XXXX</gender></teacher></school>";
    String add = "<student><name>XXXXXX</name><gender>XXXXX</gender></student>";
    StringBuilder both = new StringBuilder(xml)
            .insert(xml.indexOf("</school>"), add);
    System.out.println(both);
}
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213