user2814979
user2814979

Reputation: 57

Writing text to XML is taking long time --Java

I have some 3000 elements in arraylist.Need to write these 3000 elements to xml. The execution is taking too much time like 20 minutes in eclipse. Is there any efficient way to do this? OR any modifications to my code?

The elements in arraylist are supposed to grow in future...

MY code snippet..

---------------------------------------------------
---------------------------------------------------
for(int i=0;i<candidates.size();i++)//Candidates is my arraylist
            {
                String text=candidates.get(i);
                //System.out.println(text);
                text=text+"\n";
                file= new File("./test.xml");
                WriteToXML wr= new WriteToXML(file,"fullname",text);

            }
-------------------------------------------------------
-------------------------------------------------------
//WritetoXML class constructor
public WriteToXML(File xml,String tag,String data)
{
    try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setValidating(false);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new FileInputStream(new File(xml)));
        Element element =  doc.getDocumentElement();
        NodeList node1 = doc.getElementsByTagName(tag);
        Element fn= (Element) node1.item(0);
        Text text = doc.createTextNode(data);
        fn.appendChild(text);
        printtoXML(doc);
    } catch (Exception e) {
            System.out.println(e.getMessage());
            }
}
public static final void printtoXML(Document xml) throws Exception {
    Transformer tf = TransformerFactory.newInstance().newTransformer();
    tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    tf.setOutputProperty(OutputKeys.INDENT, "yes");
    StringWriter sw = new StringWriter();
    StreamResult result = new StreamResult(sw); 
    DOMSource source = new DOMSource(xml);
    tf.transform(source, result);
    String xmlString = sw.toString();
    File file= new File(xml);
    FileWriter fw=new FileWriter(file,false);
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write(xmlString);
    bw.flush();
    bw.close(); 
}

Upvotes: 1

Views: 1624

Answers (4)

Chip
Chip

Reputation: 3316

put the for loop inside the WriteToXML().

Main function:

file= new File("./test.xml");
WriteToXML wr= new WriteToXML(file,"fullname",candidates)

Inside WriteToXML

public WriteToXML(File xml,String tag,List candidates )
{
    try {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(false);
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(new FileInputStream(new File(xml)));
    Element element =  doc.getDocumentElement();
    NodeList node1 = doc.getElementsByTagName(tag);
    Element fn= (Element) node1.item(0);
    for (int i=0;i<candidates.size();i++) { 
        Text text = doc.createTextNode(candidates.get(i)+"\n");
        fn.appendChild(text);
    }
    printtoXML(doc);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

This way you are not re-parsing the XML all the time and write it only once.

I've tried to do minimal changes. I would not recommend doing this in the constructor - unless there is a good reason to do so.

Upvotes: 1

user2880879
user2880879

Reputation: 297

as @Masud suggests, Use SAX there is no other way. There is a great example about this Generating XML from an Arbitrary Data Structure

Upvotes: 1

Matthias
Matthias

Reputation: 3592

Right now you are doing this for each of your 3000 elements:

  1. Open the file
  2. Parse the document in there
  3. add an element to the dom structure
  4. flush the file to disk and close it

Way faster would be to do steps 1, 2 and 4 only once (1 & 2 before the loop; 4 after the loop) and just do step 3 for every element in your list (in the loop). Just write a new method which takes your tag variable and a Document instance and add the tag to the document.

What is really expensive here is the multiple conversion of Object structures to XML and back. This has a huge overhead. File IO is also giving a lot of overhead, but even this should be small compared to the multiple creation and parsing of DOM structures.

Upvotes: 2

Masudul
Masudul

Reputation: 21961

Use SAX instead of DOM. SAX is more efficient than DOM

Upvotes: 1

Related Questions