2012-05-14 31 views
3

我想知道什麼是最好的做法來解析XML是這樣的:像這個樣本解析XML的好方法?

<root> 
    <MailNotification enable="true"> 
     <To>[email protected]</To> 
     <From>[email protected]</From> 
     <Server>smtp.bar.org</Server> 
     <Port>465</Port> 
     <Username>[email protected]</Username> 
     <Password>fooo!</Password> 
    </MailNotification> 
</root> 

我使用的Java 7,完整的XML是更長的時間,但它沒有真正的大文件。我想過使用一個斯塔克斯pull解析器,因爲它似乎很容易,但有一件事我在哪裏不知道這是否真的是一個好辦法:

當來到一個MailNotification元素,我可以如創建一個新的實例一個郵件類,我沒有問題。但是:如果我來例如到要素?我怎麼知道它是否真的在MailNotification元素中,而不是直接在根下面?換句話說:我缺少的是處理諸如「現在我處於MailNotification」元素之類的狀態的最佳做法。

注:我知道我可以先驗證XML,但是想象一下,它會被允許有一個要元素一個MailNotification元素內部和要元素爲另一個孩子,語義不同的元素 - 同問題:我不知何故需要跟蹤狀態/上下文以確保我正確解釋

感謝您的任何提示!

回答

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

(*)只是澄清「最佳選擇」,它取決於你想要做什麼。
JAXB如果您的XML直接映射到您想要創建的對象,它是非常好的。
JDOM如果您想要以複雜的方式瀏覽XML,例如,如果您實現類似XPath的東西,但爲了簡單解析它的矯枉過正。這是消耗大部分內存的方法。
SAX是StAX出現之前最輕,最高效的解析器。

+0

非常感謝你,我不知道如何使用它 - 使用第二個(第3,第4 ...)while循環在主while循環內有意義。完美適合我的情況回覆。感謝所有其他人,這些鏈接中有很多有趣的東西。但是現在斯塔克斯完成了這項工作。 –

+0

+1,因爲它很短,很輕便,可以在流模式下工作,這正是我目前所需要的。 – blafasel

0

你可以看看我以前的答案:

XML response how to assign values to variables

我敢肯定,這裏有許多相同/相似的答案在SO。

至於中幾個類似的即你的問題:

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

你有開始元素/結束元素爲。

0

你會解析它與任何像樣的XML解析庫。然後,「To」將包含在「MailNotification」對象中。

有這麼多,請參閱this question作比較。我自己使用了jdom,這很容易使用,並且瞭解我非常重視哪些內容。但是,現在有更多高級替代品。

2

看看Digester。

public static final String TEST_XML = "<root>\n" + 
      "<MailNotification>\n" + 
      " <to>[email protected]</to>\n" + 
      " <from>[email protected]</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; 
    } 
+0

我實際上最終使用了Digester,非常簡單易用。感謝那偉大的提示!由於阿里安人的回答仍然接近我原來的問題,我會留下他的問題作爲正確的問題,儘管你的問題最終會對我有點幫助;-) [但這不是我原來的問題的答案意見] –

1

如何使用JAXB?你可以有一個帶註釋的java類,只需要marshall或unmarshall,這很容易。

0

詢問使用什麼工具來解析XML似乎有點像問你使用什麼編程語言:你會得到答案,說「StAX是最好的」或「JAXB是最好的」,而沒有給出他們提供什麼好處的任何理由超過其他方法。說實話,在不瞭解項目的要求和限制的情況下客觀地回答這個問題是不可能的,但對於絕大多數項目來說,使用任何流行的技術都足夠簡單,它不值得浪費時間來煩惱決策。

我可能會使用JDOM。