Hay una secuencia XML que debo analizar. Como solo necesito hacerlo una vez y construir mis objetos java, SAX parece ser la elección natural. Extiendo DefaultHandler e implementando los métodos startElement, endElement y characters, teniendo miembros en mi clase donde guardo el valor de lectura actual (tomado en el método de caracteres).Java SAX Parsing
No tengo problemas para hacer lo que necesito, pero mi código se volvió bastante complejo y estoy seguro de que no hay razón para eso y que puedo hacer las cosas de manera diferente. La estructura de mi XML es algo como esto:
<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>
Mi problema empezó cuando me di cuenta de que los mismos nombres de las etiquetas se utilizan en varias áreas del archivo. Por ejemplo, la identificación y el nombre existen tanto para un jugador como para un equipo. Quiero crear instancias de mis clases Java Player y Team. Durante el análisis, mantuve las banderas booleanas para decirme si estoy en la sección de equipos para que al final sepa que el nombre es del equipo, no del jugador, etc.
Así es como mi código es el siguiente:
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;
}
}
}
Dado que en mi escenario real que tengo más nodos a un jugador, además de los equipos y los nodos también tienen etiquetas como nombre e ID, me encontré en mal estado con varios booleanos similares a inTeamsSection y mi método endElement se vuelve largo y complejo con muchas condiciones.
¿Qué debo hacer de manera diferente? ¿Cómo puedo saber a qué etiqueta pertenece, por ejemplo?
Gracias!
Yo diría que usar SAX fue una elección natural hace unos 7 años. Actualmente, la elección natural es usar JAXB (o Xtream, o XmlBeans o JibX) – Tarlog
. Algunas veces solo tiene que hacer el análisis sintáctico manualmente. Cuando maneja megabytes de XML convirtiéndolo en objetos Java no es una buena idea. –
@ ʘleg - Si usa JAXB para desasignar objetos de StAX XMLStreamReader, puede desglosar las subsecciones de un documento más grande para administrar las restricciones de memoria. –