Modify XML Document


Java JDOM Parser – Modify XML Document


”;


Java JDOM parser is an API in java that has classes and interfaces to modify XML documents. This API represents the XML document in the form of a tree structure and each element can be retrieved easily. Hence, modification becomes an easy task. We can use setText() to modify content and addContent() to add new elements. In this chapter, we are going to see how to modify an existing XML document with two examples.

Modify XML using JDOM Parser

We can modify an XML document in java JDOM parser through following steps −

  • Step 1: Creating a SAXBuilder Object
  • Step 2: Reading the XML
  • Step 3: Parsing the XML Document
  • Step 4: Updating the content of XML document
  • Step 5: Writing the content into XML file
  • Step 6: Output to console for testing

Refer second chapter of this section for first three steps.

Step 4: Updating the content of XML document

After following the first three steps, we have successfully read the XML document we need to update. Now, we have the XML file in the form of JDOM document. To get any information from the document, firstly, we should always get the root element. After retrieving the root element, we can get the information of all the elements inside the root.

Refer this chapter of this section for steps 5 and 6.

Updating Text Content

To update text content of any element, we can use the setText() method of Element class. This method takes the text content as an argument in the form of a String. If text content already exists, it updates the old one with the new text content.

Example

Here, we have college.xml file that has three department elements. We are going to modify the staff count for department with id, 102 from 23 to 14.

<?xml version="1.0" encoding="UTF-8" standalone="no"?><college>
   <department id="101">
      <name>Computer Science</name>
      <staffCount>20</staffCount>
   </department>
   <department id="102">
      <name>Electrical and Electronics</name>
      <staffCount>23</staffCount>
   </department>
   <department id="103">
      <name>Mechanical</name>
      <staffCount>15</staffCount>
   </department>
</college>

The following ModifyTextContent.java program reads the above college.xml file using SAXBuilder object. After getting the list of department elements, we are using getAttributeValue() method to find the department with id, 102. Later, we are updating the text content using setText() method.

import java.io.File;
import java.util.List;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jdom2.transform.JDOMSource;

public class ModifyTextContent {
   public static void main(String args[]) {
      try {
	    	  
         //Creating a SAXBuilder Object
	     SAXBuilder saxBuilder = new SAXBuilder();
	          
	     //Reading the XML
	     File inputFile = new File("college.xml");
	          
	     //Parsing the XML Document
	     Document doc = saxBuilder.build(inputFile);
	         
	     //Retrieving the Root Element
	     Element RootElement = doc.getRootElement();
	     List<Element> deptList = RootElement.getChildren("department");
	         
	     //Finding "department" with id=102 in the list
	     for(int index=0; index<deptList.size();index++) {
	        Element department = deptList.get(index);
	        if(department.getAttributeValue("id").equals("102")) {
	           Element staffCount = department.getChild("staffCount");
	           //Updating the staff count
	           staffCount.setText("14");
	           break;
	        }
	     }
	     //writing the modified content into XML file
         TransformerFactory transformerFactory = TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         JDOMSource source = new JDOMSource(doc);
         StreamResult result = new StreamResult(new File("college.xml"));
         transformer.transform(source, result);

         //Output to console for testing
         XMLOutputter xmlOutput = new XMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc, System.out);
      } catch(Exception e) {
             e.printStackTrace();
	  }
   }
}

Output

Following is the updated XML document after updating staffCount.

<?xml version="1.0" encoding="UTF-8" standalone="no"?><college>
   <department id="101">
      <name>Computer Science</name>
      <staffCount>20</staffCount>
   </department>
   <department id="102">
      <name>Electrical and Electronics</name>
      <staffCount>14</staffCount>
   </department>
   <department id="103">
      <name>Mechanical</name>
      <staffCount>15</staffCount>
   </department>
</college>

Adding New Elements

The addContent() method of Element class takes child element and append it one level deep to the current element. It always adds the new Element at the end. If we pass two arguments, index and child element, then the child element gets inserted at the specified index.

Example

Now, we are going to add one more department named “Civil” to our college element in the following AddNewElements.java program. We have created the child elements of the department and added them to the department element. Later we added the department to the root element.

import java.io.File;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jdom2.transform.JDOMSource;

public class AddNewElements {
   public static void main(String args[]) {
      try {
	    	  
         //Creating a SAXBuilder Object
	     SAXBuilder saxBuilder = new SAXBuilder();
	          
	     //Reading the XML
	     File inputFile = new File("college.xml");
	          
	     //Parsing the XML Document
	     Document doc = saxBuilder.build(inputFile);
	         
	     //Retrieving the Root Element
	     Element RootElement = doc.getRootElement();
	         
	     //Creating new "department" Element
	     Element department=new Element("department");
	     department.setAttribute("id","104");
	     
	     //Creating "name" Element for department
	     Element name=new Element("name");
	     name.setText("Civil");
	     
	     //Creating "staffCount" Element for department
	     Element staffCount=new Element("staffCount");
	     staffCount.setText("18");
	     
	     //Appending Elements
	     department.addContent(name);
	     department.addContent(staffCount);
	     RootElement.addContent(department);
	     
	     //writing the modified content into XML file
         TransformerFactory transformerFactory = TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         JDOMSource source = new JDOMSource(doc);
         StreamResult result = new StreamResult(new File("college.xml"));
         transformer.transform(source, result);

         //Output to console for testing
         XMLOutputter xmlOutput = new XMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc, System.out);
      } catch(Exception e) {
             e.printStackTrace();
	  }
   }
}

Output

The updated file after adding “Civil” department is as follows :

<?xml version="1.0" encoding="UTF-8"?>
<college>
  <department id="101">
    <name>Computer Science</name>
    <staffCount>20</staffCount>
  </department>
  <department id="102">
    <name>Electrical and Electronics</name>
    <staffCount>23</staffCount>
  </department>
  <department id="103">
    <name>Mechanical</name>
    <staffCount>15</staffCount>
  </department>
  <department id="104">
    <name>Civil</name>
    <staffCount>18</staffCount>
  </department>
</college>

Advertisements

”;

Leave a Reply

Your email address will not be published. Required fields are marked *

Modify XML Document


Java StAX Parser – Modify XML Document


”;


Java StAX Parser is a java API which provides interfaces, classes and methods to parse and modify XML documents. Random access of XML elements is not possible using StAX parser and hence, we need to store the required data as the parser parses the XML document. We can use XMLEventReader to read the XML document and XMLEventWriter to write the updated content simultaneously.

Modify XML Using Java StAX Parser

We can modify an XML document in Java using StAX parser through following steps −

  • Step 1: Creating XMLInputFactory instance
  • Step 2: Reading the XML
  • Step 3: Parsing the XML
  • Step 4: Modifying the XML content
  • Step 5: Creating XMLStreamReader object
  • Step 6: writing the updated content into XML file

Refer Parse XML Document of this section for first three steps

Step 4: Modifying the XML content

After following the first three steps, we have our XML file in XMLEventReader object. Since, we don”t have random access of XML elements, we can read and write the XML content simultaneously. Here, updating means simply creating new events and adding them in the place of old events.

To create any XMLEvent, we should first get the instance of XMLEventFactory. Using XMLEventFactory, we can add new elements and attributes.

XMLEventFactory eventFactory=XMLEventFactory.newInstance();

Refer Create XML Document chapter of this section for steps 5 and 6.

Updating Text Content

The createCharacters(“text”) method of XMLEventFactory creates character content with the text specified and returns Characters event. This event can be added to the XMLEventWriter using add() function.

Example

Here is the studentData.xml file in which we need to update the marks for the student with roll number 593.

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   <student rollno = "493">
      <firstname>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singh</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

In the following UpdatingTextContent.java program, we have used two boolean variables studentFound and marksFound to identify that student with the roll number 593. We are adding all the events to XMLEventWriter except the Characters event of marks for student with roll number 593. We are creating a new Characters event for that student and adding it to the XMLEventWriter.

import java.io.FileReader;
import java.io.StringWriter;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class UpdatingTextContent {
   public static void main(String[] args) {
      try {
    	  
         //Creating XMLInputFactory instance
         XMLInputFactory factory = XMLInputFactory.newInstance();
          
         //Reading the XML
         FileReader fileReader = new FileReader("studentData.xml");
          
         //Parsing the XML
         XMLEventReader eventReader =
         factory.createXMLEventReader(fileReader); 
         
         //Updating text content
         StringWriter stringWriter = new StringWriter();
         XMLOutputFactory outFactory = XMLOutputFactory.newInstance();
         XMLEventWriter eventWriter = outFactory.createXMLEventWriter(stringWriter);
         XMLEventFactory eventFactory=XMLEventFactory.newInstance();
         
         boolean studentFound=false;
         boolean marksFound=false;
         while(eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            if(event.getEventType()==XMLStreamConstants.START_ELEMENT) {
               StartElement startElement = event.asStartElement();
               String qName = startElement.getName().getLocalPart();
               Attribute attr = startElement.getAttributeByName(new QName("rollno"));
               
               if (qName.equalsIgnoreCase("student") && attr.getValue().equals("593")) {
                  studentFound=true;
                  }
               if (qName.equalsIgnoreCase("marks") && studentFound) {
            	  studentFound = false;
            	  marksFound=true;
               }
            }
            if(event.getEventType()==XMLStreamConstants.CHARACTERS && marksFound) {
               eventWriter.add(eventFactory.createCharacters("64"));
               marksFound=false; 
            }
            else { 
               eventWriter.add(event);
            }
         }
         String xmlString = stringWriter.getBuffer().toString();
         System.out.println(xmlString);
         
      } catch (Exception e) {
         e.printStackTrace();
      } 
   }
}

The output window displays the student data with the marks modified for student with roll number 593.

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   <student rollno = "493">
      <firstname>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singh</lastname>
      <nickname>jazz</nickname>
      <marks>64</marks>
   </student>
</class>

Adding Elements to Existing XML File

The add(XMLEvent event) function of XMLEventWriter adds the event to the Writer or the OutputStream specified while creating XMLEventWriter. Adding a new StartElement event opens the new namespace scope and will be closed when an EndElement event is added.

Using the same studentData.xml file that we have discussed in the previous example, we are going to add new student element with all the necessary information.

Example

In the following AddXMLElements.java program, we have added all the events to the XMLEventWriter till the last student element. We have added the new student element at the end and then closed the root element. To find the exact position of adding the new element, we used peek() method, since it just shows the peek event instead of reading it from the stream.

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.StringWriter;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;

public class AddXMLElements {
   public static void main(String[] args) {
      try {
    	  
    	 //Creating XMLInputFactory instance
         XMLInputFactory factory = XMLInputFactory.newInstance();
         
         //Reading the XML
         FileReader fileReader = new FileReader("studentData.xml");
         
         //Parsing the XML
         XMLEventReader eventReader =
         factory.createXMLEventReader(fileReader);
         
         //Modifying the XML content
         StringWriter stringWriter = new StringWriter();
         XMLOutputFactory outFactory = XMLOutputFactory.newInstance();
         XMLEventWriter eventWriter = outFactory.createXMLEventWriter(stringWriter);
         XMLEventFactory eventFactory=XMLEventFactory.newInstance();

         while(eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            if(event.getEventType()==XMLStreamConstants.END_ELEMENT && 
            		eventReader.peek().getEventType()==XMLStreamConstants.END_DOCUMENT ) {
            
               eventWriter.add(eventFactory.createStartElement("", "", "student"));
               eventWriter.add(eventFactory.createAttribute("rollno", "693"));
                
               eventWriter.add(eventFactory.createStartElement("", "", "firstname"));
               eventWriter.add(eventFactory.createCharacters("Daniel"));
               eventWriter.add(eventFactory.createEndElement("", "", "firstname"));
                
               eventWriter.add(eventFactory.createStartElement("", "", "lastname"));
               eventWriter.add(eventFactory.createCharacters("Wesley"));
               eventWriter.add(eventFactory.createEndElement("", "", "lastname"));
                
               eventWriter.add(eventFactory.createStartElement("", "", "nickname"));
               eventWriter.add(eventFactory.createCharacters("Dany"));
               eventWriter.add(eventFactory.createEndElement("", "", "nickname"));
                
               eventWriter.add(eventFactory.createStartElement("", "", "marks"));
               eventWriter.add(eventFactory.createCharacters("75"));
               eventWriter.add(eventFactory.createEndElement("", "", "marks"));
                
               eventWriter.add(eventFactory.createEndElement("", "", "student"));
            }
            else { 
               eventWriter.add(event);
            }
         }
         
         //Creating XMLStreamReader object
         String xmlString = stringWriter.getBuffer().toString();
         ByteArrayInputStream input = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
         stringWriter.close();
         XMLStreamReader streamReader =
                 factory.createXMLStreamReader(input);
         
         //writing the updated content into XML file
         TransformerFactory transformerFactory = TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         StAXSource source = new StAXSource(streamReader);
         StreamResult result = new StreamResult(new File("studentData.xml"));
         transformer.transform(source, result);
         
         System.out.println(xmlString);
         
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Output

This is the content of the output file after adding new student information−

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   <student rollno = "493">
      <firstname>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singh</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
  <student rollno="693">
    <firstname>Daniel</firstname>
    <lastname>Wesley</lastname>
    <nickname>Dany</nickname>
    <marks>75</marks>
  </student>
</class>

Advertisements

”;

Leave a Reply

Your email address will not be published. Required fields are marked *