Category: 17. Java XML

https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyAwuaRGlDJoi0l4ODVUyPWH2fCb7MkTvp-w&s

  • 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

    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")&amp;&amp; attr.getValue().equals("593")){
                  studentFound=true;}if(qName.equalsIgnoreCase("marks")&amp;&amp; studentFound){
            	  studentFound =false;
            	  marksFound=true;}}if(event.getEventType()==XMLStreamConstants.CHARACTERS&amp;&amp; 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();}}}</code></pre>

    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">
    
      &lt;firstname&gt;dinkar&lt;/firstname&gt;
      &lt;lastname&gt;kad&lt;/lastname&gt;
      &lt;nickname&gt;dinkar&lt;/nickname&gt;
      &lt;marks&gt;85&lt;/marks&gt;
    </student> <student rollno = "493">
      &lt;firstname&gt;Vaneet&lt;/firstname&gt;
      &lt;lastname&gt;Gupta&lt;/lastname&gt;
      &lt;nickname&gt;vinni&lt;/nickname&gt;
      &lt;marks&gt;95&lt;/marks&gt;
    </student> <student rollno = "593">
      &lt;firstname&gt;jasvir&lt;/firstname&gt;
      &lt;lastname&gt;singh&lt;/lastname&gt;
      &lt;nickname&gt;jazz&lt;/nickname&gt;
      &lt;marks&gt;64&lt;/marks&gt;
    </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&amp;&amp; 
            		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();}}}</code></pre>

    Output

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

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

    Java StAX parser is a Java API that provides interfaces to create XML documents. There are cursor APIs such as XMLStreamWriter and Iterator APIs such as XMLEventWriter to create XML documents. In this chapter, we are going to use XMLStreamWriter to create XML documents. This interface has methods such as writeStartDocument(), writeStartElement(), writeCharacters() etc., to write XML content.

    Create XML using Java StAX parser

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

    • Step 1: Creating XMLStreamWriter object
    • Step 2: Writing the XML document
    • Step 3: Creating XMLStreamReader object
    • Step 4: Writing the content into file
    • Step 5: Testing the output using console

    Step 1: Creating XMLStreamWriter object

    The XMLOutputFactory is an abstract class which is used to create XMLEventWriters and XMLStreamWriters. We can either use XMLEventWriter or XMLStreamWriter objects to write XML documents.

    The createXMLStreamWriter() method of XMLOutputFactory creates an XMLStreamWriter object and the argument can be a Writer, OutputStream or any JAXP result. Here, we have created an XMLStreamWriter that writes to a Writer stream.

    XMLOutputFactory xMLOutputFactory =XMLOutputFactory.newInstance();XMLStreamWriter xMLStreamWriter = xMLOutputFactory.createXMLStreamWriter(Writer stream);

    Step 2: Writing the XML document

    The XMLStreamWriter interface has many methods that specify how to write an XML document. They are self explanatory and does not return anything, but writes the content to the Writer. Following are the most commonly used methods of XMLStreamWriter interface −

    xMLStreamWriter.writeStartDocument();
    xMLStreamWriter.writeStartElement("cars");
    xMLStreamWriter.writeCharacters("Ferrari");
    xMLStreamWriter.writeEndElement();
    xMLStreamWriter.writeEndDocument();

    Step 3: Creating XMLStreamReader object

    The XMLInputFactory is an abstract class for getting streams. Using createXMLStreamReader() method, we can create an XMLStreamReader object that allows us to read the InputStream specified. It gives forward, read-only access to the InputStream of XML data.

    XMLInputFactory factory =XMLInputFactory.newInstance();XMLStreamReader streamReader = factory.createXMLStreamReader(InputStream stream);

    Step 4: Writing the content into file

    The transform() function of Transformer class tranforms the XML source to result. Source can be of type DOMSource, SAXSource, StAXSource or StreamSource and result can be of type DOMResult, SAXResult, StAXResult or StreamResult.

    To create Transformer object, we create an instance of TransformerFactory. Here, source is of type StAXSource and result is of type StreamResult. We can create a new File object and pass this as an argument to StreamResult object.

    TransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();
    transformer.transform(source, result);

    Step 5: Testing the output using console

    We can print the file content on the console by passing ‘System.out’ as an argument for StreamResult. The transform() method of Transformer class converts the source into StreamResult and writes it on the console.

    Another way of printing the result is by simply converting the Writer object we have used for XMLStreamWriter into a String and printing that string on the console.

    StreamResult consoleResult =newStreamResult(System.out);
    transformer.transform(source, consoleResult);

    Creating Basic XML file

    The writeStartDocument() method writes the XML declaration with default version number as 1.0 and encoding as utf-8.

    The writeStartElement(“element_name”) method opens a new start tag with the specified argument name as the name of the element. The scope gets closed once we specify corresponding EndElement.

    The writeCharacters(“text_content”) method appends the specified text content to the Element.

    Example

    Here is the basic XML file we want to create −

    <?xml version="1.0" ?><cars>Ferrari</cars>

    The CreateBasicXML.java program creates cars.xml file using XMLStreamWriter class. We have used the methods writeStartDocument() to write the XML declaraction, writeStartElement(“cars”) to write the new Element named, “cars” and writeCharactrs(“Ferrari”) to write the text content. We have used writeEndElement() and writeEndDocument() methods to close the scopes correctly.

    importjava.io.ByteArrayInputStream;importjava.io.File;importjava.io.StringWriter;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLOutputFactory;importjavax.xml.stream.XMLStreamReader;importjavax.xml.stream.XMLStreamWriter;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerException;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stax.StAXSource;importjavax.xml.transform.stream.StreamResult;publicclassCreateBasicXML{publicstaticvoidmain(String[] args)throwsTransformerException{try{//creating XMLStreamWriter XMLOutputFactory xMLOutputFactory =XMLOutputFactory.newInstance();StringWriter stringWriter =newStringWriter();XMLStreamWriter xMLStreamWriter =
    
            xMLOutputFactory.createXMLStreamWriter(stringWriter);//Writing the XML document
         xMLStreamWriter.writeStartDocument();
         xMLStreamWriter.writeStartElement("cars");
         xMLStreamWriter.writeCharacters("Ferrari");
         xMLStreamWriter.writeEndElement();
         xMLStreamWriter.writeEndDocument();
         xMLStreamWriter.flush();
         xMLStreamWriter.close();//Creating XMLStreamReader objectString xmlString = stringWriter.getBuffer().toString();ByteArrayInputStream input =newByteArrayInputStream(xmlString.getBytes("UTF-8"));
         stringWriter.close();XMLInputFactory factory =XMLInputFactory.newInstance();XMLStreamReader streamReader =
                 factory.createXMLStreamReader(input);//writing the content into XML fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();StAXSource source =newStAXSource(streamReader);StreamResult result =newStreamResult(newFile("D:\\cars.xml"));
         transformer.transform(source, result);//Testing the output using consoleSystem.out.println(xmlString);}catch(Exception e){
         e.printStackTrace();}}}</code></pre>

    Output

    The XML document we have written using XMLStreamWriter is displayed as follows −

    <?xml version="1.0" ?><cars>Ferrari</cars>
    

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Creating XML file with Attributes

    The writeAttribute("attr_name","attr_value") method appends the attribute to the current element. It should be written between writeStartElement() and witeEndElement() methods. If this method is placed incorrectly out of scope of an element, it throws IllegalStateException error.

    Example

    We have to create the following cars.xml file −

    <cars><supercars company="Ferrari"><carname type="formula one">Ferrari 101</carname><carname type="sports">Ferrari 202</carname></supercars></cars>

    In the following CreateAttributes.java program, we have created two carname elements under supercar element along with attributes.

    importjava.io.ByteArrayInputStream;importjava.io.File;importjava.io.StringWriter;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLOutputFactory;importjavax.xml.stream.XMLStreamReader;importjavax.xml.stream.XMLStreamWriter;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerException;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stream.StreamResult;importjavax.xml.transform.stax.StAXSource;publicclassCreateAttributes{publicstaticvoidmain(String[] args)throwsTransformerException{try{//creating XMLStreamWriter XMLOutputFactory xMLOutputFactory =XMLOutputFactory.newInstance();StringWriter stringWriter =newStringWriter();XMLStreamWriter xMLStreamWriter =
    
            xMLOutputFactory.createXMLStreamWriter(stringWriter);//Writing the XML document
         xMLStreamWriter.writeStartDocument();
         xMLStreamWriter.writeStartElement("cars");
         xMLStreamWriter.writeStartElement("supercars");	
         xMLStreamWriter.writeAttribute("company","Ferrari");
      
         xMLStreamWriter.writeStartElement("carname");
         xMLStreamWriter.writeAttribute("type","formula one");
         xMLStreamWriter.writeCharacters("Ferrari 101");
         xMLStreamWriter.writeEndElement();
         xMLStreamWriter.writeStartElement("carname");			
         xMLStreamWriter.writeAttribute("type","sports");
         xMLStreamWriter.writeCharacters("Ferrari 202");
         xMLStreamWriter.writeEndElement();
         xMLStreamWriter.writeEndElement();
         xMLStreamWriter.writeEndDocument();
         xMLStreamWriter.flush();
         xMLStreamWriter.close();//Creating XMLStreamReader objectString xmlString = stringWriter.getBuffer().toString();ByteArrayInputStream input =newByteArrayInputStream(xmlString.getBytes("UTF-8"));
         stringWriter.close();XMLInputFactory factory =XMLInputFactory.newInstance();XMLStreamReader streamReader =
                 factory.createXMLStreamReader(input);//writing the content into XML fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();StAXSource source =newStAXSource(streamReader);StreamResult result =newStreamResult(newFile("D:\\cars.xml"));
         transformer.transform(source, result);//Testing the output using consoleSystem.out.println(xmlString);}catch(Exception e){
         e.printStackTrace();}}}</code></pre>

    Output

    The output window displays the XML content generated using XMLStreamWriter.

    <?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
    <cars>
       <supercars company = "Ferrari">
    
      &lt;carname type = "formula one"&gt;Ferrari 101&lt;/carname&gt;
      &lt;carname type = "sports"&gt;Ferrari 202&lt;/carname&gt;
    </supercars> </cars>
  • Query XML Document

    Java StAX parser is a Java API which is used to parse XML documents and query the necessary information. This API is event based and hence we need not load entire XML document to query it. As the parser identifies each event, the corresponding action is performed only when the client program implements the event.

    In this chapter, we are going to see how to query an XML document to get necessary information.

    Query XML Using Java StAX Parser

    Following are the steps we need to follow to query an XML document using Java StAX parser −

    • Step 1: Creating XMLInputFactory instance
    • Step 2: Reading the XML
    • Step 3: Parsing the XML
    • Step 4: Querying the Elements

    Step 4: Querying the Elements

    After following the first three steps, we have XMLEventReader to get events from the XML document. Using various events and by implementing them, we can query the XML document. Let us see how we can do this in detail.

    Querying Elements by Text Content

    We can get the text content in any element of an XML document by using getData().This method of Characters interface returns the character data of the current event in the form of a String. Using this method, we can query all the elements to find the required text content.

    Example

    The cars.xml file shown below has many carname elements with different text content. Let us query this file to find out if “Bentley 2” car is present.

    <?xml version = "1.0"?><cars><carname company="Ferarri" >Ferarri 101</carname><carname company="Lamborgini">Lamborgini 001</carname><carname company="Lamborgini">Lamborgini 002</carname><carname company="Lamborgini">Lamborgini 003</carname><carname company="Bentley">Bentley 1</carname><carname company="Bentley">Bentley 2</carname><carname company="Bentley">Bentley 3</carname></cars>

    The following QueryTextContent.java program reads the cars.xml file using a FileReader object. When the CHARACTERS event type is encountered, the getData() method is used to get the text content. If that data is equal to “Bentley 2”, then we are updating the ‘found’ boolean variable. In the END_DOCUMENT event, we are printing it on the console.

    importjava.io.FileReader;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.events.Characters;importjavax.xml.stream.events.XMLEvent;publicclassQueryTextContent{publicstaticvoidmain(String args[]){try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("cars.xml");//Parsing the XMLXMLEventReader eventReader =
    
          factory.createXMLEventReader(fileReader);//Querying the XMLboolean found=false;while(eventReader.hasNext()){XMLEvent event = eventReader.nextEvent();if(event.getEventType()==XMLStreamConstants.CHARACTERS){Characters characters = event.asCharacters();String textContent = characters.getData();if(textContent.equals("Bentley 2"))
              	  found=true;}if(event.getEventType()==XMLStreamConstants.END_DOCUMENT){if(found)System.out.println("Bentley 2 car is found");elseSystem.out.println("Bentley 2 car is not found");}}}catch(Exception e){
    	   e.printStackTrace();}}}</code></pre>

    Output

    Since, Bentley 2 car is present in cars.xml file, it prints that it is found.

    Bentley 2 car is found
    

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Querying Elements by Attributes

    The getAttributeByName() method of an Element interface takes the QName object which is the qualified XML name of an attribute and returns the Attribute object. Further, the getValue() method of Attribute interface is used to get the value of the attribute in the form of a String.

    Example 1

    The cars.xml file that we have used in the previous example is parsed in the following QueryAttributes.java program to count the number of Bentley cars present in the XML file. A count variable is incremented each time the company attribute of the carname element is equal to Bentley.

    importjava.io.FileReader;importjavax.xml.namespace.QName;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.events.Attribute;importjavax.xml.stream.events.StartElement;importjavax.xml.stream.events.XMLEvent;publicclassQueryExample2{publicstaticvoidmain(String args[]){try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("cars.xml");//Parsing the XMLXMLEventReader eventReader =
    
           factory.createXMLEventReader(fileReader);//Querying the XML documentint count=0;while(eventReader.hasNext()){XMLEvent event = eventReader.nextEvent();if(event.getEventType()==XMLStreamConstants.START_ELEMENT){StartElement element=event.asStartElement();QName qname=newQName("company");Attribute attr=element.getAttributeByName(qname);if(attr!=null&amp;&amp; attr.getValue().equals("Bentley"))
                   count++;}}System.out.println("No.of Bentley cars found : "+ count);}catch(Exception e){
    	   e.printStackTrace();}}}</code></pre>

    The number of Bentley cars in the XML file are displayed.

    No.of Bentley cars found : 3
    

    Example 2

    In this example, we are going to retrieve the information of a particular student based on their roll number. Here is the student.xml file we need to query −

    <?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>singn</lastname><nickname>jazz</nickname><marks>90</marks></student></class>

    In the following QueryStudent.java program, we have checked for the events START_ELEMENT, CHARACTERS and END_ELEMENT and performed actions accordingly. when the roll number attribute is equal to 393, we are printing the entire information of the student.

    importjava.io.FileReader;importjava.util.Iterator;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.events.Attribute;importjavax.xml.stream.events.Characters;importjavax.xml.stream.events.EndElement;importjavax.xml.stream.events.StartElement;importjavax.xml.stream.events.XMLEvent;publicclassQueryStudent{publicstaticvoidmain(String[] args){boolean bFirstName =false;boolean bLastName =false;boolean bNickName =false;boolean bMarks =false;boolean isRequestRollNo =false;try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("student.xml");//Parsing the XMLXMLEventReader eventReader =
    
            factory.createXMLEventReader(fileReader);//Querying the XML String requestedRollNo ="393";while(eventReader.hasNext()){XMLEvent event = eventReader.nextEvent();switch(event.getEventType()){caseXMLStreamConstants.START_ELEMENT:StartElement startElement = event.asStartElement();String qName = startElement.getName().getLocalPart();if(qName.equalsIgnoreCase("student")){Iterator&lt;Attribute&gt; attributes = startElement.getAttributes();String rollNo = attributes.next().getValue();if(rollNo.equalsIgnoreCase(requestedRollNo)){System.out.println("Start Element : student");System.out.println("Roll No : "+ rollNo);
                     isRequestRollNo =true;}}elseif(qName.equalsIgnoreCase("firstname")){
                  bFirstName =true;}elseif(qName.equalsIgnoreCase("lastname")){
                  bLastName =true;}elseif(qName.equalsIgnoreCase("nickname")){
                  bNickName =true;}elseif(qName.equalsIgnoreCase("marks")){
                  bMarks =true;}break;caseXMLStreamConstants.CHARACTERS:Characters characters = event.asCharacters();if(bFirstName &amp;&amp; isRequestRollNo){System.out.println("First Name: "+ characters.getData());
                  bFirstName =false;}if(bLastName &amp;&amp; isRequestRollNo){System.out.println("Last Name: "+ characters.getData());
                  bLastName =false;}if(bNickName &amp;&amp; isRequestRollNo){System.out.println("Nick Name: "+ characters.getData());
                  bNickName =false;}if(bMarks &amp;&amp; isRequestRollNo){System.out.println("Marks: "+ characters.getData());
                  bMarks =false;}break;caseXMLStreamConstants.END_ELEMENT:EndElement endElement = event.asEndElement();if(endElement.getName().getLocalPart().equalsIgnoreCase("student")&amp;&amp; isRequestRollNo){System.out.println("End Element : student");System.out.println();
                  isRequestRollNo =false;}break;}}}catch(Exception e){
         e.printStackTrace();}}}</code></pre>

    All the information of the student with roll number 393 is displayed.

    Start Element : student
    Roll No : 393
    First Name: dinkar
    Last Name: kad
    Nick Name: dinkar
    Marks: 85
    End Element : student
    
  • Parse XML Document

    The Java StAX parser API has classes, methods and interfaces to parse XML documents in the form of events. It is a pull based API that gives the client program more privilege to access the events only if required. In this chapter, we are going to see how to parse an XML documents in Java using StAX parser API in detail.

    Parse XML Using Java StAX Parser

    Following are the steps used while parsing a document using Java StAX Parser −

    • Step 1: Creating XMLInputFactory instance
    • Step 2: Reading the XML
    • Step 3: Parsing the XML
    • Step 4: Retrieving the Elements

    Step 1: Creating XMLInputFactory instance

    The XMLInputFactory class is an abstract class that is used to get input streams. To create a new instance of an XMLInputFactory, we use newInstance() method. If the instance of this factory cannot be loaded, it throws an error named, “FactoryConfigurationError”.

    XMLInputFactory factory =XMLInputFactory.newInstance();

    Step 2: Reading the XML

    The FileReader class is used to read streams of characters from the input file. The following statement throws “FileNotFoundException” if the file can’t be found or if the file can’t be read for some reason.

    FileReader fileReader =newFileReader("src/input.txt");

    Instead of reading XML content from the file, we can also get the content in the form of a string and convert it into bytes as follows −

    StringBuilder xmlBuilder =newStringBuilder();
    xmlBuilder.append("<class>xyz</class>");ByteArrayInputStream input =newByteArrayInputStream(xmlBuilder.toString().getBytes("UTF-8"));

    Step 3: Parsing the XML

    To parse XML events, we create XMLEventReader from the XMLInputFactory object by passing either the FileReader object or the input stream object. If the creation of XMLEventReader is not successful, it throws XMLStreamException.

    XMLEventReader eventReader = factory.createXMLEventReader(input);

    Step 4: Retrieving the Elements

    The nextEvent() method of XMLEventReader returns the next XML event in the form of XMLEvent object. The XMLEvent has methods to return events as startElement, endElement and Characters.

    XMLEvent event = eventReader.nextEvent();

    Retrieving Element Name

    To retrieve Element name, we should first get the Element from the XML document. When the event is of type XMLStreamConstants.START_ELEMENT, the asStartElement() on an XMLEvent object, retrieves the Element in the form of a StartElement object.

    The getName() method of StartElement returns the name of the Element in the form of a String.

    Example

    The RetrieveElementName.java program takes the XML content in a StringBuilder object and convert it into bytes. The obtained InputStream is used to create XMLEventReader. The Element is accessed using the events notified by the parser.

    Open Compiler

    importjava.io.ByteArrayInputStream;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.events.StartElement;importjavax.xml.stream.events.XMLEvent;publicclassRetrieveElementName{publicstaticvoidmain(String args[]){try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLStringBuilder xmlBuilder =newStringBuilder();
    
     	     xmlBuilder.append("&lt;class&gt;xyz&lt;/class&gt;");ByteArrayInputStream input =newByteArrayInputStream(xmlBuilder.toString().getBytes("UTF-8"));//Parsing the XMLXMLEventReader eventReader =
         factory.createXMLEventReader(input);//Retrieving the Elementswhile(eventReader.hasNext()){XMLEvent event = eventReader.nextEvent();if(event.getEventType()==XMLStreamConstants.START_ELEMENT){StartElement startElement = event.asStartElement();System.out.println("Element Name: "+ startElement.getName());}}}catch(Exception e){
    	  e.printStackTrace();}}}</code></pre>

    Output

    The name of the Element is displayed on the output screen.

    Element Name: class
    

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Retrieving Text Content

    To retrieve text content of an element, asCharacters() method is used on XMLEvent object. When the event is of type XMLStreamConstants.CHARACTERS, only then we can use asCharacters() method. This method returns the data in the of Characters object. The getData() method is used to get the text content in the form of a String.

    Example

    In the previous example, we have taken XML content as an Input Stream. Now, let us take input by reading from a file by saving the following XML content in a file named, classData.xml

    <class>xyz</class>

    In the following RetrievingTextContent.java program, we have read the classData.xml file using a FileReader object and passed as an input to XMLEventReader. Using, XMLEvent object, we have obtained the text content of the Element.

    importjava.io.FileReader;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.events.Characters;importjavax.xml.stream.events.XMLEvent;publicclassRetrievingTextContent{publicstaticvoidmain(String args[]){try{//Creating XMLInputFactory instanceXMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("classData.xml");//Parsing the XMLXMLEventReader eventReader =
    
         factory.createXMLEventReader(fileReader);//Retrieving the Elementswhile(eventReader.hasNext()){XMLEvent event = eventReader.nextEvent();if(event.getEventType()==XMLStreamConstants.CHARACTERS){Characters characters = event.asCharacters();System.out.println("Text Content : "+ characters.getData());}}}catch(Exception e){
    	  e.printStackTrace();}}}</code></pre>

    Output

    The text content of the element is displayed on the output screen.

    Text Content : xyz
    

    Retrieving Attributes

    The getAttributes() method of StartElement interface returns a readonly Iterator of attributes declared on this element. If there are no attributes declared on this element, it returns an empty iterator.

    The getValue() function on Attribute interface returns the value of the attribute in the form of a String.

    Example

    The following classData.xml has the information of three students along with their roll numbers as attributes. Let us retrieve this information using StAX API in Java.

    <?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>singn</lastname><nickname>jazz</nickname><marks>90</marks></student></class>

    In the following RetrieveAttributes.java program, we have used switch case statements for START_ELEMENT, CHARACTERS and END_ELEMENT XMLStreamConstants to access all the information of elements.

    importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.util.Iterator;importjavax.xml.stream.XMLEventReader;importjavax.xml.stream.XMLInputFactory;importjavax.xml.stream.XMLStreamConstants;importjavax.xml.stream.XMLStreamException;importjavax.xml.stream.events.Attribute;importjavax.xml.stream.events.Characters;importjavax.xml.stream.events.EndElement;importjavax.xml.stream.events.StartElement;importjavax.xml.stream.events.XMLEvent;publicclassRetrievingAttributes{publicstaticvoidmain(String[] args){boolean bFirstName =false;boolean bLastName =false;boolean bNickName =false;boolean bMarks =false;try{//Creating XMLInputFactory instance XMLInputFactory factory =XMLInputFactory.newInstance();//Reading the XMLFileReader fileReader =newFileReader("classData.xml");//Parsing the XMLXMLEventReader eventReader =
    
         factory.createXMLEventReader(fileReader);//Retrieving the Elementswhile(eventReader.hasNext()){XMLEvent event = eventReader.nextEvent();switch(event.getEventType()){caseXMLStreamConstants.START_ELEMENT:StartElement startElement = event.asStartElement();String qName = startElement.getName().getLocalPart();if(qName.equalsIgnoreCase("student")){System.out.println("Start Element : student");Iterator&lt;Attribute&gt; attributes = startElement.getAttributes();String rollNo = attributes.next().getValue();System.out.println("Roll No : "+ rollNo);}elseif(qName.equalsIgnoreCase("firstname")){
                  bFirstName =true;}elseif(qName.equalsIgnoreCase("lastname")){
                  bLastName =true;}elseif(qName.equalsIgnoreCase("nickname")){
                  bNickName =true;}elseif(qName.equalsIgnoreCase("marks")){
                  bMarks =true;}break;caseXMLStreamConstants.CHARACTERS:Characters characters = event.asCharacters();if(bFirstName){System.out.println("First Name: "+ characters.getData());
                  bFirstName =false;}if(bLastName){System.out.println("Last Name: "+ characters.getData());
                  bLastName =false;}if(bNickName){System.out.println("Nick Name: "+ characters.getData());
                  bNickName =false;}if(bMarks){System.out.println("Marks: "+ characters.getData());
                  bMarks =false;}break;caseXMLStreamConstants.END_ELEMENT:EndElement endElement = event.asEndElement();if(endElement.getName().getLocalPart().equalsIgnoreCase("student")){System.out.println("End Element : student");System.out.println();}break;}}}catch(FileNotFoundException e){
         e.printStackTrace();}catch(XMLStreamException e){
         e.printStackTrace();}}}</code></pre>

    Output

    All the information of students along with their roll numbers are displayed on the output screen.

    Start Element : student
    Roll No : 393
    First Name: dinkar
    Last Name: kad
    Nick Name: dinkar
    Marks: 85
    End Element : student
    
    Start Element : student
    Roll No : 493
    First Name: Vaneet
    Last Name: Gupta
    Nick Name: vinni
    Marks: 95
    End Element : student
    
    Start Element : student
    Roll No : 593
    First Name: jasvir
    Last Name: singn
    Nick Name: jazz
    Marks: 90
    End Element : student
    
  • Overview

    StAX is a Java-based API to parse XML document in a similar way as SAX parser does. But unlike SAX parser, the StAX parser API is a simple iterator based API that gives parsing control to the client program. It reads the XML document in a forward-only fashion and stores the events in an iterator.

    The client can ask for the events that he wants to access based on the event type of each event.

    Differences Between SAX and StAX Parsers

    Here are some notable differences between SAX and StAX parsers −

    SAX ParserStAX Parser
    Push based stream parserPull based stream parser
    XML documents cannot be createdXML documents cannot be created
    Gives less parsing control to client programGives more parsing control to client program
    Not Iterator based APIIterator based API
    Handler class must be implementedNo need to implement any Handler class
    Provides schema validationDoesn’t provide schema validation

    Environment Setup

    In order to use StAX parser, you should have stax.jar in your application’s classpath.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Features of StAX

    Following are the features of StAX API −

    • Reads the XML document from top to bottom and identifies the tokens.
    • Processes the tokens in the same order of their appearance.
    • Reports the parser about the nature of the tokens.
    • Invokes the callback methods in the Event handler based on the identified tokens.

    When to Use Java StAX Parser?

    You should use a StAX parser when −

    • You want to process an XML document in a linear fashion from top to bottom.
    • The document is not deeply nested.
    • Your XML document is very large.
    • The problem to be solved involves only a part of the XML document.
    • You have streaming data (data is available as soon as it is seen by the parser).

    Disadvantages of StAX

    Following are the disadvantages of StAX parser −

    • We have no random access to an XML document, since it is processed in a forward-only manner.
    • XML schema validation is not supported.
    • If you need to keep track of data that the parser has seen or where the parser has changed the order of items, then you must write the code and store the data on your own.

    XMLEvent Interface

    This interface provides the basic Event representation of all components of an XML document. The event type differentiates each event and the information is retrieved accordingly. Some of the most commonly used methods of this interface are as follows −

    MethodDescription
    StartElement asStartElement()Retrieves StartElement object from this event.
    EndElement asEndElement()Retrieves EndElement object from this event.
    Characters asCharacters()Retrieves characters such as CDATA, whitespace, etc. from this event
    int getEventType()Returns the integer code for this event.

    XMLEventReader Interface

    This interface provides iterator of events which can be used to iterate over events as they occur while parsing an XML document. Some of the most commonly used methods are listed below −

    MethodDescription
    boolean hasNext()Returns true if there are more events in the EventReader, else retruns false.
    XMLEvent nextEvent()Returns the next XMLEvent in the EventReader.
    XMLEvent peek()Returns the next XMLEvent without reading it from the stream.

    XMLEventWriter Interface

    This interface writes XML documents by adding events. Some of the most commonly used methods are listed below −

    MethodDescription
    void add(Event event)Adds the event containing elements to XML.
    void flush()Writes any cached events to the stream.
    void close()Closes all resources related to the stream.

    XMLStreamReader Interface

    This interface provides efficient way of reading XML events in a forward, read-only manner. Some of its methods are listed below −

    MethodDescription
    int next()Used to retrieve next event.
    boolean hasNext()Used to check further events exists or not.
    String getText()Used to get text of the current parsing event.
    String getLocalName()Used to get local name of the current event.

    XMLStreamWriter Interface

    This Interface provides methods to write XML documents. Some of the most commonly used methods are listed below −

    MethodDescription
    void writeStartDocument()Adds XML declaration statement to the output stream.
    void writeStartElement(String localName)Adds a start element with given name.
    void writeEndElement(String localName)Adds an end element with given name.
    void writeAttribute(String localName, String value)Writes attribute with the specified name and value to an element.
  • 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

    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.

    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.

    importjava.io.File;importjava.util.List;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stream.StreamResult;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;importorg.jdom2.output.Format;importorg.jdom2.output.XMLOutputter;importorg.jdom2.transform.JDOMSource;publicclassModifyTextContent{publicstaticvoidmain(String args[]){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLFile inputFile =newFile("college.xml");//Parsing the XML DocumentDocument doc = saxBuilder.build(inputFile);//Retrieving the Root ElementElementRootElement= doc.getRootElement();List<Element> deptList =RootElement.getChildren("department");//Finding "department" with id=102 in the listfor(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 fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();JDOMSource source =newJDOMSource(doc);StreamResult result =newStreamResult(newFile("college.xml"));
         transformer.transform(source, result);//Output to console for testingXMLOutputter xmlOutput =newXMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc,System.out);}catch(Exception e){
             e.printStackTrace();}}}</code></pre>

    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>

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    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.

    importjava.io.File;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stream.StreamResult;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;importorg.jdom2.output.Format;importorg.jdom2.output.XMLOutputter;importorg.jdom2.transform.JDOMSource;publicclassAddNewElements{publicstaticvoidmain(String args[]){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLFile inputFile =newFile("college.xml");//Parsing the XML DocumentDocument doc = saxBuilder.build(inputFile);//Retrieving the Root ElementElementRootElement= doc.getRootElement();//Creating new "department" ElementElement department=newElement("department");
    
         department.setAttribute("id","104");//Creating "name" Element for departmentElement name=newElement("name");
         name.setText("Civil");//Creating "staffCount" Element for departmentElement staffCount=newElement("staffCount");
         staffCount.setText("18");//Appending Elements
         department.addContent(name);
         department.addContent(staffCount);RootElement.addContent(department);//writing the modified content into XML fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();JDOMSource source =newJDOMSource(doc);StreamResult result =newStreamResult(newFile("college.xml"));
         transformer.transform(source, result);//Output to console for testingXMLOutputter xmlOutput =newXMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc,System.out);}catch(Exception e){
             e.printStackTrace();}}}</code></pre>

    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>
  • Create XML Document

    Java JDOM Parser is a Java API that has classes and methods to create XML documents from scratch. We can create a new JDOM document object and add elements, attributes using the methods available in Document and Element interfaces. In this chapter, we are going to use setRootElement(), addContent(), setText() and setAttribute() methods to create XML files in detail.

    Create XML using Java JDOM parser

    We can create an XML document in Java using JDOM parser through following steps −

    • Step 1: Creating JDOM Document object
    • Step 2: Creating and appending Root Element
    • Step 3: Creating elements and attributes
    • Step 4: Appending Elements to Root
    • Step 5: Writing the content into XML file
    • Step 6: Testing the output using console

    Step 1: Creating JDOM Document object

    The org.jdom2 package has Document class. It represents the XML document. This class has methods to access the root element and also the document level information. We create a new document as follows −

    Document doc =newDocument();

    Step 2: Creating and appending Root Element

    An XML document must contain a root element. We create root element using Element class of org.jdom2 package. If we provide a String to the constructor, it creates element with that supplied local name.

    The setRootElement() method in the Document class sets the root of the document. This method takes Element as an argument and sets it as the root. If the root element is already present, the old root Element gets replaced with this supplied Element.

    ElementRootElement=newElement("root");
    doc.setRootElement(RootElement);

    Step 3: Creating elements and attributes

    We can create Elements the same way we created root element in the previous step. To set an attribute to the Element, we use setAttribute() method as follows −

    Element newElement =newElement("FirstElement");
    newElement.setAttribute("attr_name","attr_value");

    Step 4: Appending Elements to Root

    The Elements created in the previous step are now attached to the root element using addContent() method. This method takes single element or collection of elements in the form of content list and adds them to the element accordingly.

    RootElement.addContent(newElement);

    Step 5: Writing the content into XML file

    The TransformerFactory class is used to create a new instance of Transformer object. Using the transform() function in Transformer class, source is transformed to the destination result. We are creating JDOMSource object by passing document as a parameter. This JDOMSource object is transformed into StreamResult as follows −

    TransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();JDOMSource source =newJDOMSource(doc);StreamResult result =newStreamResult(newFile("newFile.xml"));
    transformer.transform(source, result);

    Step 6: Testing the output using console

    This is an optional step used for testing purpose. To print the output on the console, an XMLOutputter object is created and the Document object is passed as follows −

    XMLOutputter xmlOutput =newXMLOutputter();
    xmlOutput.setFormat(Format.getPrettyFormat());
    xmlOutput.output(doc,System.out);

    Creating Simple XML File

    Using, the above mentioned steps, let us create a simple XML file that has root element alone. A new document object is created and the Root element is attached using setRootElement() method.

    The setText() method of Element object takes the text content in the form of a String and attaches it to the Element.

    Example

    Here is the XML file we need to create. It has a root element named “cars” and the text content, “Ferrari”.

    <cars>Ferrari</cars>

    The following CreateXMLFile.java creates the XML file and stores it in D drive with the file name as “cars.xml”.

    importjava.io.File;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stream.StreamResult;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.output.Format;importorg.jdom2.output.XMLOutputter;importorg.jdom2.transform.JDOMSource;publicclassCreateXMLFile{publicstaticvoidmain(String[] args){try{//Creating JDOM Document objectDocument doc =newDocument();//Creating and appending Root ElementElement carsElement =newElement("cars");
    
         carsElement.setText("Ferrari");
         doc.setRootElement(carsElement);//writing the content into XML fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();JDOMSource source =newJDOMSource(doc);StreamResult result =newStreamResult(newFile("D:\\cars.xml"));
         transformer.transform(source, result);//Output to console for testingXMLOutputter xmlOutput =newXMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc,System.out);}catch(Exception e){
         e.printStackTrace();}}}</code></pre>

    For testing purpose, we have printed the content of XML document on the console.

    <?xml version="1.0" encoding="UTF-8"?>
    <cars>Ferrari</cars>
    

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Creating Attributes

    Let us now add child elements to the root Element. Also, let us add attributes to our elements. In this example, we see how to create elements along with their attributes and attach them to the root. The setAttribute() method on each element sets the attribute and setText() method is used to set the text content of each element.

    Example

    Here is the cars.xml file that we need to create −

    <cars><supercars company="Ferrari"><carname type="formula one">Ferrari 101</carname><carname type="sports">Ferrari 202</carname></supercars></cars>

    The following CreateAttributes.java program creates the cars.xml file in D drive.

    importjava.io.File;importjavax.xml.transform.Transformer;importjavax.xml.transform.TransformerFactory;importjavax.xml.transform.stream.StreamResult;importorg.jdom2.Attribute;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.output.Format;importorg.jdom2.output.XMLOutputter;importorg.jdom2.transform.JDOMSource;publicclassCreateAttributes{publicstaticvoidmain(String[] args){try{//Creating JDOM Document objectDocument doc =newDocument();//Creating and appending Root ElementElement carsElement =newElement("cars");
    
         doc.setRootElement(carsElement);//Creating elements and attributesElement supercarElement =newElement("supercars");
         supercarElement.setAttribute("company","Ferrari");Element carElement1 =newElement("carname");
         carElement1.setAttribute("type","formula one");
         carElement1.setText("Ferrari 101");Element carElement2 =newElement("carname");
         carElement2.setAttribute("type","sports");
         carElement2.setText("Ferrari 202");
         supercarElement.addContent(carElement1);
         supercarElement.addContent(carElement2);//Appending Elements to Root
         carsElement.addContent(supercarElement);//writing the content into XML fileTransformerFactory transformerFactory =TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();JDOMSource source =newJDOMSource(doc);StreamResult result =newStreamResult(newFile("D:\\Jdomcars.xml"));
         transformer.transform(source, result);//Output to console for testingXMLOutputter xmlOutput =newXMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc,System.out);}catch(Exception e){
         e.printStackTrace();}}}</code></pre>

    The output window displays the file content as follows −

    <?xml version="1.0" encoding="UTF-8"?>
    <cars>
      <supercars company="Ferrari">
    
    &lt;carname type="formula one"&gt;Ferrari 101&lt;/carname&gt;
    &lt;carname type="sports"&gt;Ferrari 202&lt;/carname&gt;
    </supercars> </cars>
  • Query XML Document

    Java JDOM parser is an API which has classes and methods to build JDOM documents from XML files to query related information. In this chapter, we are going to query elements by text content using getText() method and to query elements by attributes, we are using getAttributeValue() method.

    Query XML Using JDOM Parser

    Following are the steps we need to follow to query an XML document using JDOM parser −

    • Step 1: Creating a SAXBuilder Object
    • Step 2: Reading the XML
    • Step 3: Parsing the XML Document
    • Step 4: Querying the Elements

    Step 4: Querying the Elements

    After completing the first three steps, we get a JDOM document. Using classes and methods present in org.jdom2 package, we can start querying the elements and their attributes.

    Now, we are going to see two examples on how to query elements based on their text content and their attributes. We use the same cars.xml file for both the examples.

    Querying Elements by TextContent

    We can query elements by their text content, by first getting the root element using getRootElement() method. After we obtain the root element, we can use getChildren() function to get all the child elements. Then, we can query the elements by text content using getText() method.

    Example

    Consider the following cars.xml file with carname elements having company attribute and text content. Now, we are going to query this XML file to find “Bentley 2” car.

    <?xml version = "1.0"?><cars><carname company="Ferarri" >Ferarri 101</carname><carname company="Lamborgini">Lamborgini 001</carname><carname company="Lamborgini">Lamborgini 002</carname><carname company="Lamborgini">Lamborgini 003</carname><carname company="Bentley">Bentley 1</carname><carname company="Bentley">Bentley 2</carname><carname company="Bentley">Bentley 3</carname></cars>

    In the following QueryXMLElements.java program, we are parsing the cars.xml file using SAXBuilder to query all the carname elements. After getting the carname elements in an Element list, we are iterating the list to find “Bentley 2” car.

    importjava.io.File;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;importjava.util.List;publicclassQueryXMLElements{publicstaticvoidmain(String args[]){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLFile inputFile =newFile("cars.xml");//Parsing the XML DocumentDocument document = saxBuilder.build(inputFile);//Retrieving the Root ElementElementRootElement= document.getRootElement();List<Element> carList =RootElement.getChildren("carname");//Finding "Bentley 2" car in the listboolean found=false;for(int index=0; index<carList.size();index++){Element car = carList.get(index);if(car.getText().equals("Bentley 2")){
    
               found=true;break;}}if(found){System.out.println("Bentley 2 car is found");}else{System.out.println("Bentley 2 car is not found");}}catch(Exception e){
    	  e.printStackTrace();}}}</code></pre>

    The output window displays that the "Bentley 2" car is found in the XML file.

    Bentley 2 car is found
    

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Querying Elements by Attributes

    Elements can also have attributes along with the text content. Now, let use the same cars.xml file to query the carname elements by their company attribute.

    The getAttributeValue("attr_name") method of Element class takes attribute name as a String argument and returns the corresponding value of the attribute.

    Example

    In the following QueryAttributes.java program, we are getting the list of carname Elements from getChildren() method. Then, we are iterating the list and incrementing the count when the company attribute value is equal to "Bentley".

    importjava.io.File;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;importjava.util.List;publicclassQueryAttributes{publicstaticvoidmain(String args[]){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLFile inputFile =newFile("cars.xml");//Parsing the XML DocumentDocument document = saxBuilder.build(inputFile);//Retrieving the Root ElementElementRootElement= document.getRootElement();List<Element> carList =RootElement.getChildren("carname");//Counting Bentley carsint count=0;for(int index=0; index<carList.size();index++){Element car = carList.get(index);if(car.getAttributeValue("company").equals("Bentley")){
    
               count++;}}System.out.println("Total number of Bentley cars : "+ count);}catch(Exception e){
    	  e.printStackTrace();}}}</code></pre>

    Output

    The count value has the number of Bentley cars in the XML file and is printed on the console.

    Total number of Bentley cars : 3
    
  • Parse XML Document

    Java JDOM Parser is an open source API in Java that has classes and methods to parse XML documents. JDOM provides random access of XML elements as it creates a tree document structure inside the memory using DOMBuilder or SAXBuilder. In this chapter, we are going to see how to build a JDOM document from an XML file using a SAX Parser.

    Parse XML Using JDOM Parser

    Following are the steps used while parsing a document using JDOM Parser −

    • Step 1: Creating a SAXBuilder Object
    • Step 2: Reading the XML
    • Step 3: Parsing the XML Document
    • Step 4: Retrieving the Elements

    Step 1: Creating a SAXBuilder Object

    JDOM document is build using a SAX Parser as follows −

    SAXBuilder saxBuilder =newSAXBuilder();

    We can also create JDOM document using an already existing DOM org.w3c.dom.Document as follows −

    DOMBuilder domBuilder =newDOMBuilder();

    Step 2: Reading the XML

    An XML file is taken into a File object as follows −

    File xmlFile =newFile("input.xml");

    We can also take XML content using StringBuilder object. Later, we can convert it into bytes for parsing.

    StringBuilder xmlBuilder =newStringBuilder(); 
    xmlBuilder.append("<?xml version="1.0"?> <rootElement></rootElement>");ByteArrayInputStream input =newByteArrayInputStream( xmlBuilder.toString().getBytes("UTF-8"));

    Step 3: Parsing the XML Document

    Using build() function, we parse an XML file or input stream. It builds the JDOM document from the given file or input stream. It throws JDOMException and IOException when there are errors in parsing the document.

    Document document = saxBuilder.build(input);

    Step 4: Retrieving the Elements

    After following the first three steps, we have successfully build JDOM document from our XML file or stream. We can now use methods available in Document and Element classes to obtain all the related information from the document.

    Retrieving Root Element

    The method getRootElement() of Document interface returns the root element of the document in the form of an Element object.

    The getName() method on Element object returns the name of the element in the form of a String.

    Example

    The following RetrieveRootElement.java program takes XML content in a StringBuilder object. It is then converted into bytes and parsed using build() function. It retrieves the root element and prints the name of the root element.

    importjava.io.ByteArrayInputStream;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;publicclassRetrieveRootElement{publicstaticvoidmain(String args[]){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLStringBuilder xmlBuilder =newStringBuilder();
    
     	     xmlBuilder.append("&lt;class&gt;&lt;/class&gt;");ByteArrayInputStream input =newByteArrayInputStream(xmlBuilder.toString().getBytes("UTF-8"));//Parsing the XML DocumentDocument document = saxBuilder.build(input);//Retrieving the Root Element NameElement root_element = document.getRootElement();System.out.println("Root Element Name : "+ root_element.getName());}catch(Exception e){
       e.printStackTrace();}}}</code></pre>

    Output

    The root element name, "class" is printed on the output screen.

    Root Element Name : class
    

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Retrieving Child Elements

    To retrieve child elements of an element, getChildren() method is used on the Element object. It returns the child elements in the form of a list. This list contains all the child elements in the of Element objects.

    To retrieve text content of an element, getText() method is used on the Element object. It returns the content between the opening and closing tags of an Element.

    Example

    Let us add three student child elements to our class element and save this file as student.xml. The name of the student is mentioned in the text content of each student element.

    <?xml version = "1.0"?><class><student>dinkar</student><student>Vaneet</student><student>jasvir</student></class>

    Now, the following java program reads the student.xml file and retrieves all the child elements along with their text content.

    importjava.io.File;importjava.util.List;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;publicclassRetrievingChildElements{publicstaticvoidmain(String[] args){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLFile inputFile =newFile("student.xml");//Parsing the XML DocumentDocument document = saxBuilder.build(inputFile);//Retrieving Root ElementElementRootElement= document.getRootElement();System.out.println("Root element :"+RootElement.getName());//Retrieving Child ElementsList<Element> studentList =RootElement.getChildren();System.out.println("----------------------------");for(int temp =0; temp < studentList.size(); temp++){Element student = studentList.get(temp);System.out.println("\nCurrent Element :"+ student.getName());System.out.println("Text Content :"+ student.getText());}}catch(Exception e){
    
         e.printStackTrace();}}}</code></pre>

    Output

    All the three child elements are displayed with their text content.

    Root element :class
    ----------------------------
    
    Current Element :student
    Text Content :dinkar
    
    Current Element :student
    Text Content :Vaneet
    
    Current Element :student
    Text Content :jasvir
    

    Retrieving Attributes

    The getAttribute("attr_name") method on an Element object takes attribute name as an argument and retrieves the attribute in the form of Attribute object. If there is no such attribute in an element, it returns null.

    The getValue() method on an Attribute object retrieves the value of the attribute as textual content.

    Example

    To student.xml file, let us add some child elements to student element along with the attribute, "rollno". Now, let us try to retrieve all this information using JDOM parser API.

    <?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>singn</lastname><nickname>jazz</nickname><marks>90</marks></student></class>

    In the following RetrievingAttributes.java program, we have first collected all the child elements in an Element list and then used getChild() method to get the details of each child inside the student element.

    importjava.io.File;importjava.util.List;importorg.jdom2.Attribute;importorg.jdom2.Document;importorg.jdom2.Element;importorg.jdom2.input.SAXBuilder;publicclassRetrievingAttributes{publicstaticvoidmain(String[] args){try{//Creating a SAXBuilder ObjectSAXBuilder saxBuilder =newSAXBuilder();//Reading the XMLFile inputFile =newFile("student.xml");//Parsing the XML DocumentDocument document = saxBuilder.build(inputFile);//Retrieving Root ElementElementRootElement= document.getRootElement();System.out.println("Root element :"+RootElement.getName());//Retrieving Child Elements and AttributesList<Element> studentList =RootElement.getChildren();System.out.println("----------------------------");for(int temp =0; temp < studentList.size(); temp++){Element student = studentList.get(temp);System.out.println("\nCurrent Element :"+ student.getName());Attribute attribute =  student.getAttribute("rollno");System.out.println("Student roll no : "+ attribute.getValue());System.out.println("First Name : "+ student.getChild("firstname").getText());System.out.println("Last Name : "+ student.getChild("lastname").getText());System.out.println("Nick Name : "+ student.getChild("nickname").getText());System.out.println("Marks : "+ student.getChild("marks").getText());}}catch(Exception e){
    
         e.printStackTrace();}}}</code></pre>

    Output

    Information of each student is dispalyed along with their roll numbers.

    Root element :class
    ----------------------------
    
    Current Element :student
    Student roll no : 393
    First Name : dinkar
    Last Name : kad
    Nick Name : dinkar
    Marks : 85
    
    Current Element :student
    Student roll no : 493
    First Name : Vaneet
    Last Name : Gupta
    Nick Name : vinni
    Marks : 95
    
    Current Element :student
    Student roll no : 593
    First Name : jasvir
    Last Name : singn
    Nick Name : jazz
    Marks : 90
    
  • Overview

    JDOM is an open source, Java-based library to parse XML documents. It is typically a Java developer friendly API. It is Java optimized and it uses Java collections like List and Arrays.

    JDOM works with DOM and SAX APIs and combines the best of the two. It is of low memory footprint and is nearly as fast as SAX.

    Environment Setup

    In order to use JDOM parser, you should have jdom.jar in your application’s classpath. Download jdom-2.0.5.zip.

    When to Use JDOM parser?

    You should use a JDOM parser when −

    • You need to know a lot about the structure of an XML document.
    • You need to move parts of an XMl document around (you might want to sort certain elements, for example).
    • You need to use the information in an XML document more than once.
    • You are a Java developer and want to leverage Java optimized parsing of XML.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    What is the result of Parsing?

    When you parse an XML document with a JDOM parser, you get the flexibility to get back a tree structure that contains all of the elements of your document without impacting the memory footprint of the application.

    JDOM provides a variety of utility functions that you can use to examine the contents and structure of an XML document in case the document is well structured and its structure is known.

    Advantages

    Following are the advantages of JDOM parser −

    • Developer friendly API.
    • Flexible and easily maintainable.
    • Lightweight and quick API
    • Well integrates with DOM and SAX standards.

    JDOM classes

    JDOM defines several Java classes. Here are the most common classes −

    ClassDescription
    DocumentRepresents an entire XML document. A Document object is often referred to as a DOM tree.
    ElementRepresents an XML element. Element object has methods to manipulate its child elements, its text, attributes, and namespaces.
    AttributeRepresents an attribute of an element. Attribute has method to get and set the value of attribute. It has parent and attribute type.
    TextRepresents the text of XML tag.
    CommentRepresents the comments in a XML document.

    JDOM Methods

    When you are working with JDOM, there are several methods you’ll use often −

    ClassDescription
    SAXBuilder.build(xmlSource)Build the JDOM document from the xml source.
    Document.getRootElement()Get the root element of the XML.
    Element.getName()Get the name of the XML node.
    Element.getChildren()Get all the direct child nodes of an element.
    Node.getChildren(Name)Get all the direct child nodes with a given name.
    Node.getChild(Name)Get the first child node with the given name.