Avatar of sdittmann
sdittmann
 asked on

Java DOM dealing with the same tag names

Hello,

I'm reading in a xml file into a java program and accessing the nodes by getElementsByTagName.  I'm running into an issue where there are duplicate tag names of <BEG> and <END> and I'm picking up the wrong information along the way.
This is apparent under the tags RATES/RS/BEG which have issues with OPS/FROM/TO/BEG.


I've tried xpath but that seems to read all the nodes in the document that I point to.  I was unable to successfully populate the java getters and setters through this method.

Any ideas on how I can loop through the 70 AVL nodes and populate my java class with all the details and deal with the duplicate tag names?

avl av = new avl();//Java class with getters and setters

NodeList avl = doc.getElementsByTagName("AVL");


NodeList nl = ele.getElementsByTagName(tagName);


String type = getTextValue(elementetd, "TYPE");
                        av.settype(type);
                  
String ospid = getTextValue(elementetd, "OSPID");
av.setOspid(ospid);
                  
            
String name = getTextValue(elementetd, "NAME");
av.setName(name);
                        
String desc = getTextValue(elementetd, "DESC");
av.setDesc(desc);
                        
String inter = getTextValue(elementetd, "INTER");
av.setInter(inter);
            
                        
String tel = getTextValue(elementetd, "TEL");
av.setTel(tel);
                        

String rates = getEstRates(elementetd, "RATE",av);  //I get bad data in here


private String getTextValue(Element ele, String tagName) {
            String textVal = null;
            NodeList nl = ele.getElementsByTagName(tagName);
            if (nl != null && nl.getLength() > 0) {
                  Element el = (Element) nl.item(0);
                  textVal = el.getFirstChild().getNodeValue();
            }

            return textVal;
      }


private String getEstRates(Element ele, String tagName, avl dt) {
            String textVal = null;
            
            ArrayList<Rates> alRates = new ArrayList<Rates>(6);
      
            NodeList nl = ele.getElementsByTagName(tagName);
            
            if (nl != null && nl.getLength() > 0) {
                  for (int i = 0; i < nl.getLength(); i++) {
                        Rates rts = new Rates();
                        Element el = (Element) nl.item(i);
                        textVal = el.getFirstChild().getNodeValue();
                        
                        rts.setRate(textVal);
                        
                        
                        
                        NodeList nlTo = ele.getElementsByTagName("BEG");
                        if (nlTo != null && nlTo.getLength() > 0){
                              
                                    Element elTo = (Element) nlTo.item(i);
                                    if(elTo != null){
                                                                  
                                          textVal = elTo.getFirstChild().getNodeValue();
                                          rts.setBeg(textVal);
                              
                                    }      
                                          
                        
                        }      
                                    alRates.add(rts);
                                    dt.setAlRates(alRates);
                        
                                    
                  } //End of Outter most for loop
                  
            
            }
            
            return textVal;
      }
      
      



There are approximately 70 AVL nodes.  2 are listed below:
<AVL>
<TYPE>OFF</TYPE>
<OSPID>934</OSPID>
<NAME>GG Garage</NAME>
<DESC>250 Clay Street</DESC>
<INTER>Clay between Front & Davis</INTER>
<TEL>(415) 433-4722</TEL>
<OPHRS>
<OPS>
<FROM>Monday</FROM>
<TO>Friday</TO>
<BEG>4:00 AM</BEG>
<END>10:00 PM</END>
</OPS>
<OPS>
<FROM>Saturday</FROM>
<BEG>7:00 AM</BEG>
<END>10:00 PM</END>
</OPS>
<OPS>
<FROM>Sunday</FROM>
<BEG>9:00 AM</BEG>
<END>10:00 PM</END>
</OPS>
</OPHRS>
<RATES>
<RS>
<DESC>Incremental</DESC>
<RATE>7</RATE>
<RQ>Per hour</RQ>
</RS>
<RS>
<DESC>24-Hour Max/Lost Tkt</DESC>
<RATE>36</RATE>
<RQ>Flat rate</RQ>
</RS>
<RS>
<DESC>Early Bird</DESC>
<RATE>20</RATE>
<RQ>Flat rate</RQ>
<RR>Mon-Fri: In by 10AM/Out by 7PM</RR>
</RS>
<RS>...</RS>
<RS>...</RS>
<RS>...</RS>
<RS>...</RS>
</RATES>
<OCC>828</OCC>
</AVL>
<AVL>...</AVL>
<AVL>
<TYPE>ON</TYPE>
<BFID>380002</BFID>
<NAME>Davis St</NAME>
<RATES>
<RS>
<BEG>12:00 AM</BEG>
<END>2:00 AM</END>
<RATE>0</RATE>
<RQ>No charge</RQ>
</RS>
<RS>
<BEG>2:00 AM</BEG>
<END>6:00 AM</END>
<RATE>0</RATE>
<RQ>Str sweep</RQ>
</RS>
<RS>
<BEG>6:00 AM</BEG>
<END>7:00 AM</END>
<RATE>0</RATE>
<RQ>No charge</RQ>
</RS>
<RS>
<BEG>7:00 AM</BEG>
<END>3:00 PM</END>
<RATE>0</RATE>
<RQ>Restricted</RQ>
</RS>
<RS>
<BEG>3:00 PM</BEG>
<END>6:00 PM</END>
<RATE>0</RATE>
<RQ>Tow away</RQ>
</RS>
<RS>
<BEG>6:00 PM</BEG>
<END>12:00 AM</END>
<RATE>0</RATE>
<RQ>No charge</RQ>
</RS>
</RATES>
<OCC>0</OCC>
</AVL>



Thanks in advance.

Java

Avatar of undefined
Last Comment
sdittmann

8/22/2022 - Mon
CEHJ

>>I've tried xpath but that seems to read all the nodes in the document that I point to.

Please show what you tried - i don't have any problem distiguishing between different types of BEG with XPath ...
ASKER CERTIFIED SOLUTION
CEHJ

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
sdittmann

ASKER
I've tried the following:

// Create a XPathFactory
XPathFactory xFactory = XPathFactory.newInstance();

// Create a XPath object
XPath xpath = xFactory.newXPath();

expr = xpath.compile("//AVL/RATES/RS/*/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
            
            // Cast the result to a DOM NodeList
            NodeList nodes = (NodeList) result;
for (int i=0; i<nodes.getLength();i++){
                  
   Log.v(TAG, "From xpath nodes.item("+i+").getNodeValue()= " + nodes.item(i).getNodeValue());
}

Which prints out the following:

08-10 16:28:05.530: VERBOSE/ParkingData(811): From xpath nodes.item(0).getNodeValue()= Incremental
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(1).getNodeValue()= 7
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(2).getNodeValue()= Per hour
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(3).getNodeValue()= 24-Hour Max/Lost Tkt
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(4).getNodeValue()= 36
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(5).getNodeValue()= Flat rate
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(6).getNodeValue()= Early Bird
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(7).getNodeValue()= 20
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(8).getNodeValue()= Flat rate
08-10 16:28:05.540: VERBOSE/ParkingData(811): From xpath nodes.item(9).getNodeValue()= Mon-Fri: In by 10AM/Out by 7PM
Etc......


It pulls out all the tags with AVL/RATES/RS/*/. in the entire document.

I'm attempting to populate each AVL obect.
How can I write the expression so I get only get the AVL/RATES/RS/* data per root element of AVL so I can populate the AVL classes getters and setters?

Thanks in advance.
mccarl

Try the following (note that this is untested but it should at least give you the idea)

 
// Create a XPathFactory
XPathFactory xFactory = XPathFactory.newInstance();

// Create a XPath object
XPath xpath = xFactory.newXPath();

expr = xpath.compile("//AVL/RATES/RS");
descExpr = xpath.compile("DESC");
rateExpr = xpath.compile("RATE");
rqExpr = cpath.compile("RQ");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
            
            // Cast the result to a DOM NodeList
            NodeList nodes = (NodeList) result;
for (int i=0; i<nodes.getLength();i++){
   // Create you AVL object here
   Avl avl = new Avl(); // Change this to whatever object represents each AVL

   avl.setDesc(descExpr.evaluate(nodes.item(i));
   avl.setRate(rateExpr.evaluate(nodes.item(i));
   avl.setRq(rqExpr.evaluate(nodes.item(i));

   // Do something with your avl object, ie. add it to a list of avl's, etc

   //avls.add(avl);                 
}

Open in new window

Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
sdittmann

ASKER
Hello mccarl.

I ran the code snippet and it did pull out the RS information.

Although I ran into two issues:

For every AVL root tag there are a varied amount(between 3 - 7) of RS nodes(Approximately 70 AVL root elements).

Is there a way I can point to a certain index of the AVL root tag and only retrieve the associated RS information?  Otherwise I can't seem to populate the Avl classes setters accurately.

The other issue was performance. It took approximately 13 minutes to process the 304 instances of the RS nodes.

Log.v(TAG, "(descExpr.evaluate(nodes.item("+i+")= " + descExpr.evaluate(nodes.item(i)));
                  Log.v(TAG, "(rateExpr.evaluate(nodes.item("+i+")= " + rateExpr.evaluate(nodes.item(i)));
                  Log.v(TAG, "(RqExpr.evaluate(nodes.item("+i+")= " + rqExpr.evaluate(nodes.item(i)));
                  Log.v(TAG, "(begExpr.evaluate(nodes.item("+i+")=" + begExpr.evaluate(nodes.item(i)));
                  Log.v(TAG, "(endExpr.evaluate(nodes.item("+i+")=" + endExpr.evaluate(nodes.item(i)));

Log sample:
08-10 21:23:15.883: VERBOSE/ParkingData(366): (descExpr.evaluate(nodes.item(0)= Incremental

08-10 21:36:14.972: VERBOSE/ParkingData(366): (rateExpr.evaluate(nodes.item(303)= 0

 Thanks for any assistance.

Steve
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
sdittmann

ASKER
Yes I'm just sequentially parsing through this xml document and populating the Avl/Rates classes with almost all of the elements in the xml document.  I was using the DOM method but ran into issue with duplicate tags in my getElementsByTagName calls.  Are there DOM work arounds to deal with duplicate tag names?  If not I'll have to look into using SAX.




Below are the Avl and Rates classes.


public class avl {

      
      
      String destination = new String();
      
      
      ArrayList<String> alOps;
      ArrayList<Rates> alRates;
      
      
      
      private String status = null;
      private String num_records = null;
      private String message = null;
      private String AVAILABILITY_UPDATED_TIMESTAMP = null;
      private String AVAILABILITY_REQUEST_TIMESTAMP = null;
      
      private String type = null;
      private String ospid = null;
      private String name = null;
      private String desc = null;
      private String inter = null;
      private String tel = null;

      private String rr = null;
      private String occ = null;
      private String oper = null;
      private String pts = null;
      private String loc = null;
      private String availSpaces = null;
      
      private String distanceFromCurrentLocation = null;
      
      protected String getOspid() {
            return ospid;
      }
      protected void setOspid(String ospid) {
            this.ospid = ospid;
      }
      protected String getStType() {
            return type;
      }
      protected void settype(String stType) {
            this.type = stType;
      }
      
      
       String getDestination() {
            return destination;
      }
       protected void setDestination(String name2) {
                  this.destination = name2;
            }
      
      
            
      public void setName(String name) {
            this.name = name;
      }
      public String getName() {
            return name;
      }
      public void setDesc(String desc) {
            this.desc = desc;
      }
      public String getDesc() {
            return desc;
      }
      public void setInter(String inter) {
            this.inter = inter;
      }
      public String getInter() {
            return inter;
      }
      public void setTel(String tel) {
            this.tel = tel;
      }
      public String getTel() {
            return tel;
      }
      
      public void setRr(String rr) {
            this.rr = rr;
      }
      public String getRr() {
            return rr;
      }
      public void setOcc(String occ) {
            this.occ = occ;
      }
      public String getOcc() {
            return occ;
      }
      public void setOper(String oper) {
            this.oper = oper;
      }
      public String getOper() {
            return oper;
      }
      public void setPts(String pts) {
            this.pts = pts;
      }
      public String getPts() {
            return pts;
      }
      public void setLoc(String loc) {
            this.loc = loc;
      }
      public String getLoc() {
            return loc;
      }
      public void setStatus(String status) {
            this.status = status;
      }
      public String getStatus() {
            return status;
      }
      public void setNum_records(String num_records) {
            this.num_records = num_records;
      }
      public String getNum_records() {
            return num_records;
      }
      public void setMessage(String message) {
            this.message = message;
      }
      public String getMessage() {
            return message;
      }
      public void setAVAILABILITY_UPDATED_TIMESTAMP(
                  String aVAILABILITY_UPDATED_TIMESTAMP) {
            AVAILABILITY_UPDATED_TIMESTAMP = aVAILABILITY_UPDATED_TIMESTAMP;
      }
      public String getAVAILABILITY_UPDATED_TIMESTAMP() {
            return AVAILABILITY_UPDATED_TIMESTAMP;
      }
      public void setAVAILABILITY_REQUEST_TIMESTAMP(
                  String aVAILABILITY_REQUEST_TIMESTAMP) {
            AVAILABILITY_REQUEST_TIMESTAMP = aVAILABILITY_REQUEST_TIMESTAMP;
      }
      public String getAVAILABILITY_REQUEST_TIMESTAMP() {
            return AVAILABILITY_REQUEST_TIMESTAMP;
      }
      public void setREQUESTED_UPDATED_TIMESTAMP(String strequestedTs) {
            // TODO Auto-generated method stub
            
      }
      
      protected ArrayList<String> getAlOps() {
            return alOps;
      }
      protected void setAlOps(ArrayList<String> alOps) {
            this.alOps = alOps;
      }
      
      protected ArrayList<Rates> getAlRates() {
            return alRates;
      }
      protected void setAlRates(ArrayList<Rates> alRates2) {
            this.alRates = alRates2;
      }
      
      
      public void setAvailSpaces(String availSpaces) {
            this.availSpaces = availSpaces;
      }
      public String getAvailSpaces() {
            return availSpaces;
      }
      public void setDistanceFromCurrentLocation(
                  String distanceFromCurrentLocation) {
            this.distanceFromCurrentLocation = distanceFromCurrentLocation;
      }
      public String getDistanceFromCurrentLocation() {
            return distanceFromCurrentLocation;
      }
      


}


public class Rates {

      private String beg = null;
      private String end = null;
      private String rate = null;
      private String rq = null;
      private String siteName = null;
      private String desc = null;
      
      
      
      
      public void setRate(String rate) {
            this.rate = rate;
      }
      public String getRate() {
            return rate;
      }
      public void setRq(String rq) {
            this.rq = rq;
      }
      public String getRq() {
            return rq;
      }
      public void setSiteName(String siteName) {
            this.siteName = siteName;
      }
      public String getSiteName() {
            return siteName;
      }
      public void setBeg(String beg) {
            this.beg = beg;
      }
      public String getBeg() {
            return beg;
      }
      public void setEnd(String end) {
            this.end = end;
      }
      public String getEnd() {
            return end;
      }
      public void setDesc(String desc) {
            this.desc = desc;
      }
      public String getDesc() {
            return desc;
      }
      
      /**<BEG>7:00 PM</BEG>
      <END>12:00 AM</END>
      <RATE>0</RATE>
      <RQ>No charge</RQ>  **/
      
      
      
}

Thanks.
sdittmann

ASKER
I'll research the SAX options as well.
Thanks.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.