2010-12-10 67 views
0

我正在從我的教授提供的一個示例中工作,該示例從天氣預報站點獲取數據並解析XML文件以顯示列表中的天氣情況。我的程序是類似的,但我想要檢索嵌套在幾個節點中的信息,但我不知道如何去實現它。下面是我從工作的XML文件:解析XML和檢索信息幾層節點Deep Java/Android

<?xml version="1.0" encoding="UTF-8"?> 
<DirectionsResponse> 
<status>OK</status> 
<route> 
    <summary>S Street Viaduct</summary> 
    <leg> 
    <step> 
    <travel_mode>DRIVING</travel_mode> 
    <start_location> 
    <lat>40.7021400</lat> 
    <lng>-74.0158200</lng> 
    </start_location> 
    <end_location> 
    <lat>40.7021400</lat> 
    <lng>-74.0158200</lng> 
    </end_location> 
    <polyline> 
    <points>kslwFzewbM</points> 
    <levels>B</levels> 
    </polyline> 
    <duration> 
    <value>0</value> 
    <text>1 min</text> 
    </duration> 
    <html_instructions>Head &lt;b&gt;east&lt;/b&gt; on &lt;b&gt;S Street Viaduct&lt;/b&gt;</html_instructions> 
    <distance> 
    <value>0</value> 
    <text>1 ft</text> 
    </distance> 
    </step> 
    <duration> 
    <value>0</value> 
    <text>1 min</text> 
    </duration> 
    <distance> 
    <value>0</value> 
    <text>1 ft</text> 
    </distance> 
    <start_location> 
    <lat>40.7021400</lat> 
    <lng>-74.0158200</lng> 
    </start_location> 
    <end_location> 
    <lat>40.7021400</lat> 
    <lng>-74.0158200</lng> 
    </end_location> 
    <start_address>S Street Viaduct, New York, NY 10004, USA</start_address> 
    <end_address>S Street Viaduct, New York, NY 10004, USA</end_address> 
    </leg> 
    <copyrights>Map data ©2010 Google, Sanborn</copyrights> 
    <overview_polyline> 
    <points>kslwFzewbM</points> 
    <levels>B</levels> 
    </overview_polyline> 
</route> 
</DirectionsResponse> 

我真的只是在檢索中的「html_instructions」標籤中的信息感興趣,但它嵌套在「路線」,「腿」,並「步」標籤。我已經看到了關於解析XML的幾個教程和問題,但似乎無法找到解決方案。任何方向將不勝感激!

謝謝。

回答

4

所以基本上使用SAX解析器對你來說是個不錯的選擇(它速度很快,可以過濾掉所有不必要的數據,消耗較少的內存)。第一次使用SAX時,您可能會發現以下示例很有用。我沒有說代碼是完美的(它錯過了例如異常處理,安全流關閉等),但它可能是一個很好的起點。

 

import java.io.FileInputStream; 
import java.io.InputStream; 
import java.util.ArrayList; 
import java.util.List; 

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

public class Test { 

    private static final String HTML_INSTRUCTIONS = "html_instructions"; 

    public static void main(String[] args) throws Exception { 
    final List htmlInstructions = new ArrayList(); 

    SAXParserFactory spf = SAXParserFactory.newInstance(); 
    SAXParser sp = spf.newSAXParser(); 
    DefaultHandler dh = new DefaultHandler() { 
     private boolean isHtmlInstructions = false; 
     private StringBuilder sb = new StringBuilder(); 
     @Override 
     public void startElement(String uri, String localName, String name, 
      Attributes attributes) throws SAXException { 
     super.startElement(uri, localName, name, attributes); 
     if (HTML_INSTRUCTIONS.equals(name)) { 
      isHtmlInstructions = true; 
     } 
     } 

     @Override 
     public void characters(char ch[], int start, int length) 
     throws SAXException { 
     if (isHtmlInstructions) { 
      sb.append(ch, start, length); 
     } 
     } 

     @Override 
     public void endElement(String uri, String localName, String name) 
      throws SAXException { 
     super.endElement(uri, localName, name); 
     if (HTML_INSTRUCTIONS.equals(name)) { 
      htmlInstructions.add(sb.toString()); 
      sb.delete(0, sb.length()); 
      isHtmlInstructions = false; 
     } 
     } 
    }; 

    InputStream is = new FileInputStream("test.xml"); 
    sp.parse(is, dh); 
    for (String htmlInstruction : htmlInstructions) { 
     System.out.println(htmlInstruction); 
    } 

    } 

} 
 

輸出應該是這樣的:

 

Head <b>east on <b>S Street Viaduct</b> 
 
+0

非常感謝這個迴應!這真的幫助我瞭解發生了什麼。 我沒有提到我試圖從網絡中解析生成的xml文件,這似乎使事情變得複雜,然後將內容顯示爲網頁。 從我的教授的前我看到,我可以創建一個HttpRequest實例,然後 HttpGet getMethod = new HttpGet(ADDRESS); 然後使用responseHandler以String形式獲取文件。但後來我不確定如何將SAX代碼和HttpRequest結合在一起。我希望這很清楚。我將在整個週末爲此工作,因此非常感謝任何見解。 – malfunction 2010-12-11 21:22:45

+0

這取決於「網絡上的文件」和「將內容顯示爲網頁」的含義。如果它是一個URL始終相同的文件,則可以輕鬆使用java.net.URLConnection類並將該文件作爲java.io.InputStream獲取。我建議像使用流一樣處理文件,特別適用於生成的文件,這些文件很容易變得非常大。然後你可以生成一個HTML文件作爲輸出。或者您正在使用JavaServlet,XML文件將由用戶上傳,並且輸出將作爲對Web瀏覽器的直接響應而生成? – 2010-12-12 09:51:30

3

使用SAX,只關注html_instructions標籤。您的處理程序將爲每個元素調用startElement()並傳入元素的名稱中。將該名稱與"html_instructions"進行比較。匹配時,請注意所有已處理的節點,直到相應的endElement()呼叫。

+0

謝謝,CommonsWare - 我的手機編程當然是用你的書的忙編碼器的指南Android開發&這是偉大的! – malfunction 2010-12-11 21:24:35

+0

@malfunction:很高興你喜歡它! – CommonsWare 2010-12-11 21:43:02