xml - Java SAX Parsing -


there's xml stream need parse. since need once , build java objects, sax looks natural choice. i'm extending defaulthandler , implementing startelement, endelement , characters methods, having members in class save current read value (taken in characters method).

i have no problem doing need, code got quite complex , i'm sure there's no reason , can things differently. structure of xml this:

<players>   <player>     <id></id>     <name></name>     <teams total="2">       <team>         <id></id>         <name></name>         <start-date>           <year>2009</year>           <month>9</month>         </start-date>         <is-current>true</is-current>       </team>       <team>         <id></id>         <name></name>         <start-date>           <year>2007</year>           <month>11</month>         </start-date>         <end-date>           <year>2009</year>           <month>7</month>         </end-date>       </team>     </teams>   </player> </players> 

my problem started when realized same tag names used in several areas of file. example, id , name exist both player , team. want create instances of java classes player , team. while parsing, kept boolean flags telling me whether i'm in teams section in endelement know name team's name, not player's name , on.

here's how code looks like:

public class myparser extends defaulthandler {      private string currentvalue;     private boolean inteamssection = false;     private player player;     private team team;     private list<team> teams;      public void characters(char[] ch, int start, int length) throws saxexception {         currentvalue = new string(ch, start, length);     }      public void startelement(string uri, string localname, string name, attributes attributes) throws saxexception {         if(name.equals("player")){             player = new player();         }         if (name.equals("teams")) {             inteamssection = true;             teams = new arraylist<team>();         }         if (name.equals("team")){             team = new team();         }     }         public void endelement(string uri, string localname, string name) throws saxexception {         if (name.equals("id")) {             if(inteamssection){                 team.setid(currentvalue);             }             else{                 player.setid(currentvalue);             }         }         if (name.equals("name")){             if(inteamssection){                 team.setname(currentvalue);             }             else{                 player.setname(currentvalue);             }         }         if (name.equals("team")){             teams.add(team);         }         if (name.equals("teams")){             player.setteams(teams);             inteamssection = false;         }     } } 

since in real scenario have more nodes player in addition teams , nodes have tags name , id, found myself messed several booleans similar inteamssection , endelement method becomes long , complex many conditions.

what should differently? how can know name tag, instance, belongs to?

thanks!

there 1 neat trick when writing sax parser: allowed change contenthandler of xmlreader while parsing. allows separate parsing logic different elements multiple classes, makes parsing more modular , reusable. when 1 handler sees end element switches parent. how many handlers implement left you. code this:

public class roothandler extends defaulthandler {     private xmlreader reader;     private list<team> teams;      public roothandler(xmlreader reader) {         this.reader = reader;         this.teams = new linkedlist<team>();     }      public void startelement(string uri, string localname, string name, attributes attributes) throws saxexception {         if (name.equals("team")) {             // switch handler parse team element             reader.setcontenthandler(new teamhandler(reader, this));         }     } }  public class teamhandler extends defaulthandler {     private xmlreader reader;     private roothandler parent;     private team team;     private stringbuilder content;      public teamhandler(xmlreader reader, roothandler parent) {         this.reader = reader;         this.parent = parent;         this.content = new stringbuilder();         this.team = new team();     }      // characters can called multiple times per element aggregate content in stringbuilder     public void characters(char[] ch, int start, int length) throws saxexception {         content.append(ch, start, length);     }      public void startelement(string uri, string localname, string name, attributes attributes) throws saxexception {         content.setlength(0);     }      public void endelement(string uri, string localname, string name) throws saxexception {         if (name.equals("name")) {             team.setname(content.tostring());         } else if (name.equals("team")) {             parent.addteam(team);             // switch handler our parent             reader.setcontenthandler(parent);         }     } } 

Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -