3 Stimmen

Gute Möglichkeit, XML wie dieses Beispiel zu parsen?

Ich frage mich, was ist die beste Praxis zu parsen XML wie diese:

<root>
    <MailNotification enable="true">
        <To>foo@bar.org</To>
        <From>foo@bar.org</From>
        <Server>smtp.bar.org</Server>
        <Port>465</Port>
        <Username>foo@bar.org</Username>
        <Password>fooo!</Password>
    </MailNotification>
</root>

Ich verwende Java 7, das komplette XML ist länger, aber es ist keine wirklich große Datei. Ich dachte über die Verwendung eines Stax Pull Parser, weil es einfach schien, aber es gibt eine Sache, wo ich nicht sicher bin, ob es wirklich ein guter Weg ist:

Wenn Sie zu einem MailNotification-Element Ich könnte z.B. eine neue Instanz von z.B. einer Mailklasse erstellen, damit habe ich kein Problem. Aber: Was ist, wenn ich z.B. zu einer Zum Element ? Woher weiß ich, dass es sich wirklich innerhalb eines MailNotification-Elements befindet und nicht direkt unter dem Root? Mit anderen Worten: Was mir fehlt, ist eine Best Practice für den Umgang mit Zuständen wie "jetzt bin ich in einem MailNotification"-Element.

Anmerkung: Ich weiß, dass ich die XML zuerst überprüfen könnte, aber ich stelle mir vor, dass es erlaubt wäre, eine Zum Element innerhalb einer MailNotification-Element und eine Zum Element als Kinder eines anderen, semantisch anderen Elements - dasselbe Problem: Ich muss irgendwie den Überblick über die Zustände / den Kontext behalten, um sicherzustellen, dass ich die Zum Element richtig.

Danke für jeden Hinweis!

4voto

Cephalopod Punkte 13896

StAX Stream Reader sind die beste* Wahl. Verwenden Sie einfach den Java-Stack, um Ihren Status zu halten, wie in diesem Beispiel. Die Konstanten sind XMLStreamConstants .

XMLStreamReader reader;

void parseRoot() {
    reader.require(START_ELEMENT, null, "root");

    while (reader.nextTag() == START_ELEMENT) {
        switch (reader.getLocalName()) {
        case "MailNotification":
            MailNotification mail = parseMail();
            // do something with mail
            break;
        // more cases
        }
    }

    reader.require(END_ELEMENT, null, "root");
}

MailNotification parseMail() {
    reader.require(START_ELEMENT, null, "MailNotification");
    MailNotification mail = new MailNotification();

    while (reader.nextTag() == START_ELEMENT) {
        switch (reader.getLocalName()) {
        case "To":
            mail.setTo(parseString());
            break;
        // more cases
        }
    }

    reader.require(END_ELEMENT, null, "MailNotification");
    return mail;
}

String parseString() {
    String text = "";
    if (reader.next() == CHARACTERS) {
        text = reader.getText();
        reader.next();
    }
    return text;
}

(*) Nur um die Frage nach der "besten Wahl" zu klären: Es kommt darauf an, was Sie tun wollen.
JAXB ist sehr gut geeignet, wenn Ihr XML direkt auf die Objekte abgebildet wird, die Sie erstellen möchten.
JDOM ist nützlich, wenn Sie XML auf komplexe Weise navigieren wollen, z. B. wenn Sie etwas wie XPath implementieren; aber für einfaches Parsing ist es zu viel. Dies ist der Ansatz, der den meisten Speicher verbraucht.
SAX war der leichteste und effizienteste Parser, bevor es StAX gab.

2voto

hammarback Punkte 753

Werfen Sie einen Blick auf Digester.

public static final String TEST_XML = "<root>\n" +
          "<MailNotification>\n" +
          " <to>foo@bar.org</to>\n" +
          " <from>foo@bar.org</from>\n" +
          " </MailNotification>\n" +
          "</root>";

Digester digester = new Digester();
digester.setValidating(false);

digester.addObjectCreate("root/MailNotification", MailNotification.class);
digester.addBeanPropertySetter("root/MailNotification/to", "to");
digester.addBeanPropertySetter("root/MailNotification/from", "from");

MailNotification notification = (MailNotification) digester.parse(new StringReader(TEST_XML));
System.out.println(notification.getTo());
System.out.println(notification.getFrom());

public class MailNotification {
  private String to;
  private String from;

  public String getTo() {
    return to;
  }

  public void setTo(String to) {
    this.to = to;
  }

  public String getFrom() {
    return from;
  }

  public void setFrom(String from) {
    this.from = from;
  }

1voto

kukudas Punkte 4716

Wie wäre es mit der Verwendung von JAXB ? Sie können eine Java-Klasse mit Annotationen haben und müssen nur marshall oder unmarshall, die ganz einfach ist.

0voto

ant Punkte 22080

Sie können einen Blick auf meine vorherige Antwort werfen:

XML-Antwort, wie man Variablen Werte zuweist

Und ich bin sicher, dass es viele gleiche/ähnliche Antworten hier auf SO gibt.

Zu Ihrer Frage unter wenigen ähnlichen d.h. :

How do I know if it is really inside a MailNotification element and not directly below the root?

Sie haben dafür ein Startelement/Endelement.

0voto

eis Punkte 48781

Sie können es mit jeder anständigen XML-Parsing-Bibliothek parsen. Dann würde ein "To" in einem "MailNotification"-Objekt enthalten sein.

Davon gibt es viele, siehe diese Frage zum Vergleich. Ich habe verwendet jdom Ich selbst finde es einfach zu bedienen und zu verstehen, was ich sehr schätze. Heutzutage gibt es jedoch fortschrittlichere Alternativen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X