Существует поток XML, который мне нужно проанализировать. Поскольку мне нужно только сделать это один раз и построить мои объекты Java, SAX выглядит как естественный выбор. Я расширяю DefaultHandler и реализую методы startElement, endElement и characters, имея членов в моем классе, где я сохраняю текущее значение чтения (взятое в методе символов).Java SAX Parsing
У меня нет проблем делать то, что мне нужно, но мой код довольно сложный, и я уверен, что для этого нет причин, и я могу делать что-то по-другому. Структура моего 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. Во время разбора я сохранил логические флаги, говорящие мне, есть ли я в разделе команд, чтобы в конце этого элемента я узнал, что имя - это имя команды, а не имя игрока и т. Д.
Вот как мой код выглядит следующим образом:
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;
}
}
}
Поскольку в моем реальном сценарии я больше узлов на игрока в дополнение к командам, и эти узлы имеют метки, как имя и идентификатор, я обнаружил, перепутались с несколькими булерами, подобными inTeamsSection, и мой метод endElement становится длинным и сложным со многими условиями.
Что мне делать по-другому? Как я могу узнать, к чему принадлежит тег имени?
Спасибо!
Я бы сказал, что использование SAX было естественным выбором около 7 лет назад. В настоящее время естественным выбором является использование JAXB (или Xtream, или XmlBeans или JibX). – Tarlog
Иногда вам просто нужно вручную разобрать парсинг. Когда вы имеете дело с мегабайтами XML-преобразования его в объекты Java, это не очень хорошая идея. –
@ ʘleg - Если вы используете JAXB для демонтажа объектов из StAX XMLStreamReader, вы можете отключить подразделы большего документа для управления ограничениями памяти. –