Results 1 to 7 of 7

Thread: DOM XML Parsing

  1. #1
    Alfaromeo is offline Member
    Join Date
    Feb 2014
    Posts
    6
    Rep Power
    0

    Default DOM XML Parsing

    Sample XML:
    XML Code:
    <Books>
    <Book id="1" Name="C#">
    <URL>http://localhost/download/M1.xml</URL>
    </Book>
    
    <Book id="2" Name="Oracle">
    <URL>http://localhost/download/M2.xml</URL>
    </Book>
    
    <Book id="3" Name="Archius">
    <URL>http://localhost/download/M3.xml</URL>
    <URL>http://localhost/download/M4.xml</URL>
    </Book>
    </Books>
    I have to fetch only the book name attribute and use it for display .However say for example ,I have got the list of Books ie(C#,Oracle,Archius) ,passing this value to a method should return me an array of URL nodes value within it.

    The idea is to display the book names in a list and then on user selection , corresponding URL needs to be fetched.

    Was able to get the loop for traversing the nodes
    [java=code]
    NodeList nodeList = document.getDocumentElement().getElementsByTagName ("Book");
    for (int i = 0; i < nodeList.getLength(); i++) {...
    [java=code]
    SO
    a) Display the BookNames
    b) Get the corresponding URL's for the particular book if I pass the Bookname

  2. #2
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: DOM XML Parsing

    Firstly, do familiarise yourself with the org.w3c.dom package. See org.w3c.dom (Java Platform SE 7 ). I find that unless I work with the DOM API for a stretch of time, I need to refer to the API docs the find the right methods to use. You too should refer to the docs.

    To get the book names, i.e., the Name attribute of the Book element, all you need is

    Java Code:
    Element elem = (Element) nodeList.item(i);
    elem.getAttribute("Name");  // Assign this to a variable, or add to a List, etc. - up to you
    Note that the cast to Element should be safe in this case as you previously obtained nodeList through a call to getElementsByTagName().

    Getting the URL(s) (note: the Archius book has 2 URLs) given a book name involves a few more steps. The following is a quick sample of one way to do this:

    Java Code:
    private Collection<String> getURLs(String bookName) {
    	Collection<String> urls = new HashSet<String>();
    	
    	NodeList nodeList = doc.getElementsByTagName("Book");
    	
    	for (int i = 0; i < nodeList.getLength(); i++) {
    		Element elem = (Element) nodeList.item(i);
    		if (elem.getAttribute("Name").equals(bookName)) {
    			NodeList bookChildNodes = elem.getChildNodes();
    			
    			for (int j = 0; j < bookChildNodes.getLength(); j++) {
    				Node bookChildNode = bookChildNodes.item(j);
    				String bookChildNodeName = bookChildNode.getNodeName();
    				System.out.println(bookChildNodeName);
    				
    				if (bookChildNodeName.equals("URL")) {
    					urls.add(bookChildNode.getTextContent());
    				}
    			}
    			break;
    		}
    	}
    
    	return urls;
    }
    You'd see that it:
    1. gets a NodeList of Book elements
    2. for each element, gets the element whose Name attribute corresponds to the desired book name
    3. for the found element, gets a NodeList of its child nodes
    4. for each child node, checks that the node name is URL (inspect the print out of the child node names to see why this is necessary!)
    5. for the found child URL node, gets the text content


    Note that this is not a particularly efficient way to get the URLs given a book name, but it illustrates how to traverse the DOM. There are a number of ways to improve its efficiency, which I'll leave as an exercise for you. Note also that there are other techniques that you can use to do this, e.g., by using XPath. Look it up!

    HTH.

  3. #3
    Alfaromeo is offline Member
    Join Date
    Feb 2014
    Posts
    6
    Rep Power
    0

    Default Re: DOM XML Parsing

    Thanks for the pointers and yes XPath is the way to go.Tyring to list the booknames into a string array , but only the first bookname is populated.

    public String[] getBookNames(){
    String[] bookList = null;
    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList result = null;
    try {
    result = (NodeList) xPath.evaluate("/Books/Book", document, XPathConstants.NODESET);
    } catch (XPathExpressionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }System.out.println(result.getLength());
    for(int i=0;i<result.getLength();i++)
    {
    Element elem = (Element) result.item(i);

    System.out.println(elem.getAttribute("Name"));
    bookList[i]=elem.getAttribute("Name");
    }
    return bookList;
    }

  4. #4
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: DOM XML Parsing

    You sure? It works for me, i.e., the array is populated with all 3 book names. Is result.getLength() returning 1? You might want to paste here your other bits of code, especially the bit the sets up 'document'.

  5. #5
    Alfaromeo is offline Member
    Join Date
    Feb 2014
    Posts
    6
    Rep Power
    0

    Default Re: DOM XML Parsing

    Yes it shows total length as 3 , but seems only adds one book name which prints c# and it exits. Here is the class for your reference

    package com.Download;

    import java.util.Collection;
    import java.util.HashSet;

    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;

    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.Element;

    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathConstants;
    import javax.xml.xpath.XPathExpressionException;
    import javax.xml.xpath.XPathFactory;


    public class XMLParser {

    private final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    private DocumentBuilder builder;
    private NodeList nodeList;
    private Document document;

    public XMLParser()
    {
    try{
    builder = factory.newDocumentBuilder();
    document = builder.parse("http://localhost/download/MediaManager.xml");
    //nodeList = document.getDocumentElement().getElementsByTagName ("Book");
    }catch(Exception e){}

    }

    public String[] getBookNames(){
    String[] bookList = null;
    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList result = null;
    try {
    result = (NodeList) xPath.evaluate("/Books/Book", document, XPathConstants.NODESET);
    } catch (XPathExpressionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }//System.out.println(result.getLength());
    for(int i=0;i<result.getLength();i++)
    {
    Element elem = (Element) result.item(i);

    System.out.println(i);
    bookList[i]=elem.getAttribute("Name");
    }
    return bookList;
    }


    public Collection<String> getURLs(String bookID) {
    Collection<String> urls = new HashSet<String>();
    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList bookChildNodes = null;
    try{
    bookChildNodes = (NodeList) xPath.evaluate("/Books/Book/[@id=" + bookID, document, XPathConstants.NODESET);
    }catch(XPathExpressionException e){e.printStackTrace();}

    for (int j = 0; j < bookChildNodes.getLength(); j++) {
    Node bookChildNode = bookChildNodes.item(j);
    String bookChildNodeName = bookChildNode.getNodeName();
    System.out.println(bookChildNodeName);

    if (bookChildNodeName.equals("URL")) {
    urls.add(bookChildNode.getTextContent());
    }
    }
    return urls;
    }


    }

    The only thing is that I'm reading from the URL , the XML doucument

  6. #6
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: DOM XML Parsing

    Your XMLParser class has a bug... where bookList[i]=elem.getAttribute("Name"); causes a NullPointerException. This is because bookList hasn't been initialised.

    Once that's been fixed, and the builder.parse() code replaced with a file directly from my file system, getBookNames() does get all 3 books.

    Below is my full working code listing. If it still doesn't work properly for you, then I suspect your MediaManager.xml file is formatted differently from your previous sample XML file. (I've also rectified your getURLs method. Note how the XPath expression is constructed.)

    Java Code:
    import java.io.File;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.HashSet;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathConstants;
    import javax.xml.xpath.XPathExpressionException;
    import javax.xml.xpath.XPathFactory;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NodeList;
    
    public class XMLParser {
    
    	private final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    	private DocumentBuilder builder;
    	private NodeList nodeList;
    	private Document document;
    
    	public XMLParser() {
    		try {
    			builder = factory.newDocumentBuilder();
    
    			document = builder.parse(new File("/home/jashburn/tmp/books.xml"));
    //			document = builder.parse("http://localhost/download/MediaManager.xml");
    			// nodeList = document.getDocumentElement().getElementsByTagName ("Book");
    		}
    		catch (Exception e) {
    			e.printStackTrace();
    		}
    
    	}
    
    	public String[] getBookNames() {
    		XPath xPath = XPathFactory.newInstance().newXPath();
    		NodeList result = null;
    		try {
    			result = (NodeList) xPath.evaluate("/Books/Book", document, XPathConstants.NODESET);
    		}
    		catch (XPathExpressionException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}// System.out.println(result.getLength());
    
    		String[] bookList = new String[result.getLength()];
    		for (int i = 0; i < result.getLength(); i++) {
    			Element elem = (Element) result.item(i);
    
    			System.out.println(i);
    			bookList[i] = elem.getAttribute("Name");
    		}
    		return bookList;
    	}
    
    	public Collection<String> getURLs(String bookID) {
    		Collection<String> urls = new HashSet<String>();
    		XPath xPath = XPathFactory.newInstance().newXPath();
    
    		NodeList urlNodes = null;
    		try {
    			urlNodes = (NodeList) xPath.evaluate("/Books/Book[@id=" + bookID + "]/URL", document,
    				XPathConstants.NODESET);
    			for (int j = 0; j < urlNodes.getLength(); j++) {
    				urls.add(urlNodes.item(j).getTextContent());
    			}
    		}
    		catch (XPathExpressionException e) {
    			e.printStackTrace();
    		}
    				
    		return urls;
    	}
    	
    	public static void main(String[] args) {
    		XMLParser parser = new XMLParser();
    		System.out.println(Arrays.deepToString(parser.getBookNames()));
    		
    		Collection<String> urls = parser.getURLs("3");
    		System.out.println(urls.toString());
    	}
    
    }

  7. #7
    Alfaromeo is offline Member
    Join Date
    Feb 2014
    Posts
    6
    Rep Power
    0

    Default Re: DOM XML Parsing

    Thanks for your patience, I learned some new things and it is finally solved.

Similar Threads

  1. XML parsing with SAX
    By Prime624 in forum New To Java
    Replies: 2
    Last Post: 05-19-2013, 10:10 PM
  2. parsing CSV
    By dewitrydan in forum New To Java
    Replies: 10
    Last Post: 03-31-2011, 07:09 PM
  3. help with parsing
    By ace_03 in forum New To Java
    Replies: 15
    Last Post: 11-24-2009, 10:02 PM
  4. XML parsing using DOM
    By alley in forum XML
    Replies: 4
    Last Post: 10-14-2009, 07:17 PM
  5. Xml Parsing
    By Nomad in forum XML
    Replies: 12
    Last Post: 02-22-2009, 12:19 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •