Java SAX-Parsing
Gibt es einen XML-stream, die ich brauche, zu analysieren. Da brauche ich nur einmal machen und bauen meine java-Objekte, SAX sieht aus wie die Natürliche Wahl. Ich bin DefaultHandler erweitern und die Umsetzung der startElement, endElement und characters Methoden, mit Mitglieder in meiner Klasse, wo ich speichern Sie den aktuellen Wert Lesen (in der Zeichen-Methode).
Ich habe kein problem, zu tun, was ich brauche, aber mein code ziemlich Komplex und ich bin sicher, es gibt keinen Grund dafür, und das kann ich alles anders machen.
Die Struktur der XML-ist so etwas wie dieses:
<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>
Mein problem begann, als ich erkannte, dass die gleichen tag-Namen sind verwendet in mehreren Bereichen der Datei. Zum Beispiel id und name bestehen für beide einen Spieler und ein team. Ich möchte Sie zum erstellen von Instanzen der java-Klassen Spieler und Mannschaft. Während der Analyse, die ich gehalten boolean-flags sagen mir, ob ich in den teams-Abschnitt, so dass in der endElement weiß ich, dass der name, ist ein team-Namen, nicht den Namen des Spielers und so weiter.
Hier ist, wie mein code sieht wie folgt aus:
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;
}
}
}
Da in meiner realen Szenario habe ich mehr Knoten an, die ein Spieler zusätzlich zu den teams und diese Knoten-auch tags wie name und id, ich fand mich Durcheinander mit mehreren booleans ähnlich wie die inTeamsSection und meine endElement Methode wird lang und Komplex mit vielen Bedingungen.
Was sollte ich anders machen? Wie kann ich wissen, was für ein name-tag, zum Beispiel, gehört?
Dank!
InformationsquelleAutor der Frage Haji | 2011-12-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist ein ordentlicher trick beim schreiben der SAX-parser: Es ist erlaubt zu ändern
ContentHandler
eines XMLReader während der Analyse. Dies ermöglicht das trennenparsing Logik für die verschiedenen Elemente, die in mehrere Klassen, die macht der
analysieren mehr modular und wiederverwendbar. Wenn ein handler sieht seinem Ende-element
schaltet zurück zu seinen Eltern. Wie viele Handler implementieren Sie würden gelassen werden, um
Sie. Der code würde wie folgt Aussehen:
InformationsquelleAutor der Antwort Jörn Horstmann
Es ist schwierig zu raten ohne zu wissen, mehr über Ihre Anforderungen, sondern die Tatsache, dass Sie überrascht sind, dass "mein code ziemlich Komplex" deutet darauf hin, dass Sie waren nicht gut informiert, wenn Sie sich entschieden SAX. SAX ist ein low-level Programmier-Schnittstelle in der Lage, sehr hohe Leistung, aber das ist, weil der parser ist dabei weit weniger Arbeit für Sie, und daher benötigen Sie eine Menge tun, um mehr sich selbst arbeiten.
InformationsquelleAutor der Antwort Michael Kay
Empfehle ich dringend, zu stoppen analysieren Sie sich selbst und schnappen Sie sich gute XML-data-binding-Bibliothek. XStream (http://x-stream.github.io/) ist vielleicht persönlicher Favorit, aber es gibt viele verschiedene Bibliotheken. Es kann sogar in der Lage zu analysieren, Ihre POJOs auf der Stelle, ohne die Konfiguration benötigt (wenn Sie Namen für die Eigenschaft und Pluralisierung entsprechend der XML-Struktur).
InformationsquelleAutor der Antwort Konstantin Pribluda
Ich etwas sehr ähnlich, aber anstatt
boolean
Flaggen, um mir zu sagen, in welchem Zustand ich bin, ich test fürplayer
oderteam
als nicht-null
. Macht die Dinge ein bisschen ordentlicher. Dies erfordert, dass Sie, um Sie zunull
wenn Sie feststellen, dass das Ende jedes Elements, nachdem Sie Hinzugefügt haben, wird es zu der entsprechenden Liste.InformationsquelleAutor der Antwort Graham Borland
Wenn Sie brauchen, hübscher code verwenden Sie bitte StAX, diese Vergleich aller XML-parsing APIs deutet darauf hin, dass StAX ist eine viel bessere option.
StAX Leistung in den meisten tests besser ist als die jeder anderen API-Implementierung zu.
Also ich persönlich sehe keinen Grund zu gehen mit SAX, es sei denn, Sie machen einige legacy-bezogenen Programmierung.
InformationsquelleAutor der Antwort Oleg Mikheev