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
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();
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.
importjava.io.FileReader;importjava.io.StringWriter;importjavax.xml.namespace.QName;importjavax.xml.stream.XMLEventFactory;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLEventWriter;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLOutputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.events.Attribute;importjavax.xml.stream.events.StartElement;importjavax.xml.stream.events.XMLEvent;publicclassUpdatingTextContent{publicstaticvoidmain(String[] args){try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("studentData.xml");//Parsing the XMLXMLEventReader eventReader =
factory.createXMLEventReader(fileReader);//Updating text contentStringWriter stringWriter =newStringWriter();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(newQName("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>
Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.
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.
importjava.io.ByteArrayInputStream;importjava.io.File;importjava.io.FileReader;importjava.io.StringWriter;importjavax.xml.stream.XMLEventFactory;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLEventWriter;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLOutputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.XMLStreamReader;importjavax.xml.stream.events.XMLEvent;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stax.StAXSource;importjavax.xml.transform.stream.StreamResult;publicclassAddXMLElements{publicstaticvoidmain(String[] args){try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("studentData.xml");//Parsing the XMLXMLEventReader eventReader =
factory.createXMLEventReader(fileReader);//Modifying the XML contentStringWriter stringWriter =newStringWriter();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 objectString xmlString = stringWriter.getBuffer().toString();ByteArrayInputStream input =newByteArrayInputStream(xmlString.getBytes("UTF-8"));
stringWriter.close();XMLStreamReader streamReader =
factory.createXMLStreamReader(input);//writing the updated content into XML fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();StAXSource source =newStAXSource(streamReader);StreamResult result =newStreamResult(newFile("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>
Leave a Reply