Link to home
Start Free TrialLog in
Avatar of newtosql
newtosql

asked on

Reading xml file

Hello All,

I have a xml file like below.

<main>
<traffic1>
<light1>on</light1>
<light2>off</light2>
<light3>on</light3>
...so on
</traffic1>

<traffic2>
<light1>on</light1>
<light2>off</light2>
<light3>on</light3>
...so on
</traffic2>
</main>

I would like to read this xml file from java file, which will be singleton and will be loaded at the start...so that, i can access the parameters thereon in any of my web page without loading the xml file again.

Any ideas how to read?? Singleton class is not a problem...but, reading is a problem for me.
thanks and regards
newtosql



Avatar of victorli
victorli
Flag of China image

Try this code to see if it will satisfy your need. I run the them using Java 1.4.1. Java 1.4.1 has got Dom 2 API and  
this is all I need.


import java.io.*;

import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.*;



public class TrafficInformer {
    private static TrafficInformer   mTrafficInformer;
    private Element                  mTraffic1;
    private Element                  mTraffic2;
       
   
    private TrafficInformer(String xmlFile)
        throws Exception
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new FileInputStream(xmlFile));
        Element root = doc.getDocumentElement();        
        mTraffic1 = (Element)root.getElementsByTagName("traffic1").item(0);
        mTraffic2 = (Element)root.getElementsByTagName("traffic2").item(0);
    }

    public String getTraffic1(int lightNo)
    {
        Element elementForlightNo = (Element)mTraffic1.getElementsByTagName("light"+lightNo).item(0);
        return ((Text)elementForlightNo.getFirstChild()).getData();
    }
   
    public String getTraffic2(int lightNo)
    {
        Element elementForlightNo = (Element)mTraffic2.getElementsByTagName("light"+lightNo).item(0);
        return ((Text)elementForlightNo.getFirstChild()).getData();
    }

    public static TrafficInformer create(String xmlFile)
        throws Exception
    {
        if (mTrafficInformer == null) {
            mTrafficInformer = new TrafficInformer(xmlFile);
        }
        return mTrafficInformer;
    }
   
    public static void main(String[] args)
        throws Exception
    {
        TrafficInformer ti = TrafficInformer.create(args[0]);
        System.out.println(" light 2 of traffic1 is :" + ti.getTraffic1(2));
        System.out.println(" light 1 of traffic2 is :" + ti.getTraffic2(1));
    }
}
test the above program use:

java TrafficInformer xmlFile
Sorry, just re-read your questions and find the following code may be better.

import java.io.*;

import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.*;



public class TrafficInformer2 {
    private static final String XMLFILE = "a.xml";
   
    private static TrafficInformer2   mTrafficInformer;
    private Element                  mTraffic1;
    private Element                  mTraffic2;
       
   
    private TrafficInformer2(String xmlFile) throws Exception
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new FileInputStream(xmlFile));
        Element root = doc.getDocumentElement();        
        mTraffic1 = (Element)root.getElementsByTagName("traffic1").item(0);
        mTraffic2 = (Element)root.getElementsByTagName("traffic2").item(0);
    }

    public String getTraffic1(int lightNo)
    {
        Element elementForlightNo = (Element)mTraffic1.getElementsByTagName("light"+lightNo).item(0);
        return ((Text)elementForlightNo.getFirstChild()).getData();
    }
   
    public String getTraffic2(int lightNo)
    {
        Element elementForlightNo = (Element)mTraffic2.getElementsByTagName("light"+lightNo).item(0);
        return ((Text)elementForlightNo.getFirstChild()).getData();
    }

    public static TrafficInformer2 create()
        throws Exception
    {
        if (mTrafficInformer == null) {
            mTrafficInformer = new TrafficInformer2(XMLFILE);
        }
        return mTrafficInformer;
    }
   
    public static void main(String[] args)
        throws Exception
    {
        TrafficInformer2 ti = TrafficInformer2.create();
        System.out.println(" light 2 of traffic1 is :" + ti.getTraffic1(2));
        System.out.println(" light 1 of traffic2 is :" + ti.getTraffic2(1));
    }
}
Sorry, just re-read your questions and find the following code may be better.

import java.io.*;

import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.*;



public class TrafficInformer2 {
    private static final String XMLFILE = "a.xml";
   
    private static TrafficInformer2   mTrafficInformer;
    private Element                  mTraffic1;
    private Element                  mTraffic2;
       
   
    private TrafficInformer2(String xmlFile) throws Exception
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new FileInputStream(xmlFile));
        Element root = doc.getDocumentElement();        
        mTraffic1 = (Element)root.getElementsByTagName("traffic1").item(0);
        mTraffic2 = (Element)root.getElementsByTagName("traffic2").item(0);
    }

    public String getTraffic1(int lightNo)
    {
        Element elementForlightNo = (Element)mTraffic1.getElementsByTagName("light"+lightNo).item(0);
        return ((Text)elementForlightNo.getFirstChild()).getData();
    }
   
    public String getTraffic2(int lightNo)
    {
        Element elementForlightNo = (Element)mTraffic2.getElementsByTagName("light"+lightNo).item(0);
        return ((Text)elementForlightNo.getFirstChild()).getData();
    }

    public static TrafficInformer2 create()
        throws Exception
    {
        if (mTrafficInformer == null) {
            mTrafficInformer = new TrafficInformer2(XMLFILE);
        }
        return mTrafficInformer;
    }
   
    public static void main(String[] args)
        throws Exception
    {
        TrafficInformer2 ti = TrafficInformer2.create();
        System.out.println(" light 2 of traffic1 is :" + ti.getTraffic1(2));
        System.out.println(" light 1 of traffic2 is :" + ti.getTraffic2(1));
    }
}
ASKER CERTIFIED SOLUTION
Avatar of victorli
victorli
Flag of China image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of newtosql
newtosql

ASKER

Hii Victorli,

You are charm!!! Thanks for spending time for my question...actually i made a little change and did it generalised by passing the name of the element...

import java.io.*;

import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.*;



public class TrafficInformer2 {
   private static final String XMLFILE = "a.xml";
   
   private static TrafficInformer2   mTrafficInformer;
   private Element                  mTraffic1;
   private Element                  mTraffic2;
     
   
   private TrafficInformer2(String xmlFile) throws Exception
   {
       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
       DocumentBuilder builder = factory.newDocumentBuilder();
       Document doc = builder.parse(new FileInputStream(xmlFile));
       Element root = doc.getDocumentElement();        
       mTraffic1 = (Element)root.getElementsByTagName("traffic1").item(0);
       mTraffic2 = (Element)root.getElementsByTagName("traffic2").item(0);
   }

   public String getTraffic1(String lightNo)
   {
       Element elementForlightNo = (Element)mTraffic1.getElementsByTagName(lightNo).item(0);
       return ((Text)elementForlightNo.getFirstChild()).getData();
   }
   
   public String getTraffic2(String lightNo)
   {
       Element elementForlightNo = (Element)mTraffic2.getElementsByTagName(lightNo).item(0);
       return ((Text)elementForlightNo.getFirstChild()).getData();
   }

   public static TrafficInformer2 create()
       throws Exception
   {
       if (mTrafficInformer == null) {
           mTrafficInformer = new TrafficInformer2(XMLFILE);
       }
       return mTrafficInformer;
   }
   
}

It's working fine...but, do you think it is all right if i do the above.

thanks and regards.
newtosql
Yes, you are absolutely right and thanks for your points.
Hello victorli,

I made some more changes to ur class and make it totally generalised...It's working...but, i m not sure whether that'S the perfect way or not, moreover i do suppose that this will remain work as a singleton....just take a look...sorry for bothering u again...if u want, i can give more points for the same question.


import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;



public class TrafficInformer2 {
   
   
   private org.w3c.dom.Document document = null;


   private static TrafficInformer2   mTrafficInformer;
   private Element  mTraffic;
     
   
   private TrafficInformer2()
   {
   }

   public void setTraffic(String trafficname)
   {
       Element root = document.getDocumentElement();        
       mTraffic = (Element)root.getElementsByTagName(trafficname).item(0);
   }

   
   public String getTrafficValue(String lightNo)
   {
        Element elementForlightNo = (Element)mTraffic.getElementsByTagName(lightNo).item(0);
       return ((Text)elementForlightNo.getFirstChild()).getData();
   }
   

   public org.w3c.dom.Document getDocument()
         {
                 return document;
         }

     
     public void setXMLFile(String inFile) {
         try
           {
                    javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
                         javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
                         document = builder.parse( new java.io.File(inFile) );
                 }
                 catch (javax.xml.parsers.ParserConfigurationException e1)
                 {
                         System.out.println("PCE");
                 }
                 catch (org.xml.sax.SAXException e2)
                 {
                         System.out.println("SE");
                 }
                 catch (java.io.IOException e3)
                 {
                         System.out.println("IOE");
                 }

     }

   public static TrafficInformer2 getInstance() throws Exception
   {
       if (mTrafficInformer == null) {
           mTrafficInformer = new TrafficInformer2();
       }
       return mTrafficInformer;
   }
   
}

And the following is the way i m using it in jsp

TrafficInformer2 ts = TrafficInformer2.getInstance();
        ts.setXMLFile("D:/a.xml");
        ts.setTraffic("traffic1");
        String light1 = ts.getTrafficValue("light1");
        String light2 = ts.getTrafficValue("light2");
         
       ts.setTraffic("traffic2");
        String light3 = ts.getTrafficValue("light1");
        String light4 = ts.getTrafficValue("light2");
       

       out.println(" light1 from traffic1:" + light1);
       out.println(" light2 from traffic1:" + light2);
       out.println(" light1 from traffic2" + light3);
       out.println(" light2 from traffic2" + light4);

Please guide
thanks and regards
newtosql
Your changes have got the following advantages:
(1) Your class can dynmically load different xml file.
(2) If your document has "traffic3", "traffic4" ..., you need not add methods "getTraffic3()", "getTraffic4()"...

For (2), I donot think the "mTraffic" is necessary. Because the "document" instance variable store everything we need. I prefer the following code:

public class TrafficInformer2 {  
  private org.w3c.dom.Document document = null;
  private static TrafficInformer2   mTrafficInformer;
 
  private TrafficInformer2()
  {
  }
 
  public String getTrafficValue(String trafficname, String lightNo)
  {
      Element root = document.getDocumentElement();        
      Element  traffic = (Element)root.getElementsByTagName(trafficname).item(0);
       Element elementForlightNo = (Element)traffic.getElementsByTagName(lightNo).item(0);
      return ((Text)elementForlightNo.getFirstChild()).getData();
  }
 

  public org.w3c.dom.Document getDocument()
        {
                return document;
        }

   
    public void setXMLFile(String inFile) {
        try
          {
                   javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
                        javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
                        document = builder.parse( new java.io.File(inFile) );
                }
                catch (javax.xml.parsers.ParserConfigurationException e1)
                {
                        System.out.println("PCE");
                }
                catch (org.xml.sax.SAXException e2)
                {
                        System.out.println("SE");
                }
                catch (java.io.IOException e3)
                {
                        System.out.println("IOE");
                }

    }

  public static TrafficInformer2 getInstance() throws Exception
  {
      if (mTrafficInformer == null) {
          mTrafficInformer = new TrafficInformer2();
      }
      return mTrafficInformer;
  }
 
you testing code will like this:
TrafficInformer2 ts = TrafficInformer2.getInstance();
       ts.setXMLFile("D:/a.xml");
       String light1 = ts.getTrafficValue("traffic1","light1");

It is simpler to use and you also save the memory to store the extra instance variable "mTracffic".      
Even for the following code, I may replace "document" with "root" element so the getTrafficValue() method will be simpler like this:
     Element  traffic = (Element)root.getElementsByTagName(trafficname).item(0);
      Element elementForlightNo = (Element)traffic.getElementsByTagName(lightNo).item(0);
     return ((Text)elementForlightNo.getFirstChild()).getData();

"root" or "document" is not important, but definitely I will rename them as "mRoot" or "mDocument". I always name instance variable different from local variables(in this case they should be "root" or "document").  It makes the program more readable.

We can see, there are many design issues even for such a simple class. How about a complicated big system? To make a system working is easy, but to create a flexiblewe, manageablt, extensible system is not easy. This is why the software architect is paid so much but we programmer and developer are not paid that good. Architects do lots of good design for a system.
Hii victoli,

Thanks for your very kind help. Well,i m a newbie..and wanted to learn more and more from you experts. You are right in both technical information.

Keep up the good work
thanks and regards
newtosql