我需要解析一个XML流。由于我只需要执行一次并构建我的Java对象,所以SAX看起来是自然的选择。我正在扩展DefaultHandler并实现startElement,endElement和characters方法,在类中具有成员变量,其中我保存当前读取的值(在characters方法中获取)。
我没有问题地完成了我需要做的事情,但是我的代码变得相当复杂,我确信没有必要这样做,我可以用不同的方式处理。我的XML结构大致如下:
<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>
当我意识到文件的几个区域中使用了相同的标签名称时,我的问题就开始了。例如,id和name都用于一个球员和一支队伍。我想创建我的Java类Player和Team的实例。在解析过程中,我保持布尔标志以告诉我是否在团队部分,这样在endElement中,我将知道该名称是团队的名称,而不是球员的名称等。
以下是我的代码:
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;
}
}
}
因为在我的实际场景中,除了团队之外,我还有更多的节点与玩家相关,并且这些节点也有像名称和ID这样的标签。我发现自己陷入了许多布尔值类似于inTeamsSection的混乱中,而我的endElement方法变得又长又复杂,有许多条件。
我应该怎么做才能不同呢?例如,我如何知道名称标签属于哪个节点?
谢谢!