3

次のように XML を解析するためのベスト プラクティスは何だろうと思っています。

<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>

私は Java 7 を使用しています。完全な XML は長くなりますが、それほど大きなファイルではありません。簡単に思えたので、Stax Pull Parser を使用することを考えましたが、それが本当に良い方法かどうか確信が持てないことが 1 つあります。

MailNotification 要素になると、たとえば、メール クラスなどの新しいインスタンスを作成できますが、それで問題はありません。しかし、例えばTo 要素に来たらどうしますか? それが本当に MailNotification 要素内にあり、ルートの直下にないかどうかを確認するにはどうすればよいですか? 言い換えれば、私が見逃しているのは、「今私は MailNotification にいる」要素のような状態を処理するためのベスト プラクティスです。

注: 最初に XML を検証できることはわかっていますが、To 要素をMailNotification 要素内に持ち、To 要素別の意味的に異なる要素の子として持つことができると想像してください。同じ問題: どうにかして状態を追跡する必要があります。 / コンテキストを調べて、 To 要素が正しく解釈されるようにします。

ヒントをありがとう!

4

6 に答える 6

4

StAX Stream Reader が最良の選択です*。この例のように、Java スタックを使用して状態を維持するだけです。定数は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;
}

(*) 「最良の選択」を明確にするために、それはあなたが何をしたいかによって異なります。
作成するオブジェクトに XML が直接マップされる場合、 JAXBは非常に優れています。
JDOMは、複雑な方法で XML をナビゲートしたい場合に便利です。たとえば、XPath のようなものを実装する場合などです。しかし、単純な解析ではやり過ぎです。これは、ほとんどのメモリを消費するアプローチです。
SAXは、StAX が登場する前は、最も軽量で効率的なパーサーでした。

于 2012-05-14T20:24:24.297 に答える
2

ダイジェストを見てください。

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;
  }
于 2012-05-14T20:32:59.593 に答える
1

JAXBを使用するのはどうですか。注釈付きの Java クラスを作成し、マーシャリングまたはアンマーシャリングを行うだけで十分です。これは非常に簡単です。

于 2012-05-14T20:47:10.177 に答える
0

私の以前の回答を見ることができます:

XML 応答 変数に値を割り当てる方法

そして、ここSOには同じ/類似の答えがたくさんあると確信しています。

いくつかの類似した質問の中であなたの質問について:

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

そのための開始要素/終了要素があります。

于 2012-05-14T20:26:08.337 に答える
0

適切な XML 解析ライブラリで解析します。次に、「To」は「MailNotification」オブジェクト内に含まれます。

そのようなものがたくさんあります。比較のためにこの質問を参照してください。私は自分自身でjdomを使用しました。使いやすく、どれを重視しているかを理解するのは簡単です。ただし、最近ではより高度な代替手段があります。

于 2012-05-14T20:28:01.447 に答える
0

XML を解析するためにどのツールを使用するかを尋ねることは、使用しているプログラミング言語を尋ねることに少し似ているように思えます。「StAX が最適です」または「JAXB が最適です」という答えが得られますが、他のアプローチよりもどのような利点があるかについては何の正当化もされません。正直に言うと、プロジェクトの要件と制約について詳しく知らずに、この質問に客観的に答えることは不可能ですが、大部分のプロジェクトでは、一般的なテクノロジを使用してタスクを十分に簡単に行うことができるため、時間をかけて時間を無駄にする価値はありません。決断。

おそらくJDOMを使用するでしょう。

于 2012-05-14T22:22:14.930 に答える