2017-08-17 60 views
2

我是編程中的新手,爲了更好地提高我對android中解析xml的理解,我試圖從web服務中獲取一些關於地震的數據。我已經閱讀了Stackoverflow和其他教程中的所有相關主題,但是我的代碼中存在錯誤。 下面是從XML的摘錄我想分析:用xmlpullparser寫入Xml文件夾

<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> 
<q:quakeml xmlns:q="http://quakeml.org/xmlns/quakeml/1.2" xmlns="http://quakeml.org/xmlns/bed/1.2" xmlns:ingv="http://webservices.ingv.it/fdsnws/event/1"> 
    <eventParameters publicID="smi:webservices.ingv.it/fdsnws/event/1/query">  
     <event publicID="smi:webservices.ingv.it/fdsnws/event/1/query?eventId=16736781">  
      <type>earthquake</type>  
      <description>   
       <type>region name</type>   
       <text>Tirreno Meridionale (MARE)</text>  
      </description>  
      <preferredMagnitudeID>smi:webservices.ingv.it/fdsnws/event/1/query?magnitudeId=49992691</preferredMagnitudeID>  
      <preferredOriginID>smi:webservices.ingv.it/fdsnws/event/1/query?originId=49089691</preferredOriginID>  
      <creationInfo>   
       <agencyID>INGV</agencyID>   
       <author>SURVEY-INGV</author>   
       <creationTime>2017-08-16T14:59:48</creationTime>  
      </creationInfo> 

而下面是我寫的代碼部分:

private static List<Earthquake> extractFeatureFromQuakeml(String earthquakeXML) throws XmlPullParserException, IOException { 

    XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance(); 
    xmlFactoryObject.setNamespaceAware(true); 
    XmlPullParser myparser = xmlFactoryObject.newPullParser(); 

    myparser.setInput(new StringReader(earthquakeXML)); 

    // If the JSON string is empty or null, then return early. 
    if (TextUtils.isEmpty(earthquakeXML)) { 
     return null; 
    } 

    // Create an empty ArrayList that we can start adding earthquakes to 
    List<Earthquake> earthquakes = new ArrayList<>(); 

    try { 
     int eventType = myparser.getEventType(); 
     Log.d("Step", "Started parsing"); 

     while (eventType != XmlPullParser.END_DOCUMENT) { 
      String location = ""; 
      String time = ""; 
      double magnitude = 0.0; 
      String url = ""; 
      String tag = myparser.getName(); 
      String text = ""; 

      switch (eventType) { 
       case XmlPullParser.START_TAG: 
        //Log.d("Step","Started parsing, end tag: " + tag); 
        if (tag.equalsIgnoreCase("event")) { 
         url = myparser.getAttributeValue(null, "publicID"); 
         Log.d(LOG_TAG, "Url" + url); 
         myparser.next(); 
        } 

        break; 

       case XmlPullParser.END_TAG: 
        text = myparser.getText(); 
        if (text != null) { 
         if (tag.equalsIgnoreCase("type") && text.equalsIgnoreCase("region name")) { 
          myparser.nextText(); 
          location = "" + myparser.getText(); 
          Log.d(LOG_TAG, "Location" + location); 
         } 
        } 

        if (tag.equalsIgnoreCase("creationTime")) { 
         time = "" + myparser.getText(); 
         Log.d(LOG_TAG, "Time" + time); 
        } 

        if (tag.equalsIgnoreCase("mag")) { 
         myparser.next(); 
         myparser.next(); 
         String smagnitude = myparser.getText(); 
         Log.d(LOG_TAG, "Magnitude" + smagnitude); 
        } 

        if (tag.equalsIgnoreCase("creationTime")) { 
         time = "" + myparser.getText(); 
         Log.d(LOG_TAG, "Time" + time); 
        } 

        if (tag.equalsIgnoreCase("mag")) { 
         myparser.next(); 
         myparser.next(); 
         String smagnitude = myparser.getText(); 
         Log.d(LOG_TAG, "Magnitude" + smagnitude); 
        } 

        break; 
      } 

      // Create a new {@link Earthquake} object with the magnitude, location, time, 
      // and url from the JSON response. 
      if (location != null && magnitude != 0.0 && time != null && url != null) { 
       Earthquake earthquake = new Earthquake(magnitude, location, time, url); 
       // Add the new {@link Earthquake} to the list of earthquakes. 
       earthquakes.add(earthquake); 
      } 

      eventType = myparser.next(); 
     } 

    } catch (XmlPullParserException e) { 

     Log.e("QueryUtils", "Problem parsing the earthquake XML results", e); 
    } 

    // Return the list of earthquakes 
    return earthquakes; 
} 

現在我得到的唯一的價值是url,其他變量始終爲空。 有人可以指出我的代碼中的缺陷嗎?並且請溫柔一點,我已經開始編碼僅僅3周前:)

非常感謝!

+0

而不是使用XmlPullParserFactory和XmlPullParser。您可以使用XML轉換器來使用Retrofit庫。請整合翻新並遵循https://futurestud.io/tutorials/retrofit-how-to-integrate-xml-converter – Rajesh

回答

0

你的方法的問題是你每次在你的while循環中都是空的,你應該明白while循環會多次調用(例如當你得到Url並將該值存儲在url中,並且你正在調用myparser.next();所以它會得到下一個元素type,它會進入while循環現在你正在刪除每個值,你也刪除url值。)。

相反,你可以創建一個Earthquake對象時,你得到的開始標記爲event和每一個結束標籤,你可以在Earthquake對象,並在event末標籤添加coressponding值時,Earthquake對象添加到列表中。

我很少修改你的代碼是如何做到這一點,你可以將所有剩餘的值

private static List<Earthquake> extractFeatureFromQuakeml(String earthquakeXML) throws XmlPullParserException, IOException { 

    XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance(); 
    xmlFactoryObject.setNamespaceAware(true); 
    XmlPullParser myparser = xmlFactoryObject.newPullParser(); 

    myparser.setInput(new StringReader(earthquakeXML)); 

    // If the JSON string is empty or null, then return early. 
    if (TextUtils.isEmpty(earthquakeXML)) { 
     return null; 
    } 

    // Create an empty ArrayList that we can start adding earthquakes to 
    List<Earthquake> earthquakes = new ArrayList<>(); 

    try { 
     int eventType = myparser.getEventType(); 
     Log.d("Step", "Started parsing"); 

     Earthquake earthquake = null; 

     while (eventType != XmlPullParser.END_DOCUMENT) { 
      // String location = ""; 
      // String time = ""; 
      // double magnitude = 0.0; 
      // String url = ""; 
      String tag = myparser.getName(); 
      String text = ""; 

      switch (eventType) { 
       case XmlPullParser.START_TAG: 
        //Log.d("Step","Started parsing, end tag: " + tag); 
        if (tag.equalsIgnoreCase("event")) { 
         url = myparser.getAttributeValue(null, "publicID"); 
         Log.d(LOG_TAG, "Url" + url); 
         myparser.next(); 

         // We are creating Earthquake here 
         earthquake = new Earthquake(); 

         earthquake.setUrl(url); 
        } 

        break; 

       case XmlPullParser.END_TAG: 
        text = myparser.getText(); 
        if (text != null) { 
         if (tag.equalsIgnoreCase("type") && text.equalsIgnoreCase("region name")) { 
          myparser.nextText(); 
          earthquake.setLocation(myparser.getText()); 
          Log.d(LOG_TAG, "Location" + earthquake.getLocation()); 
         } 
        } 

        if (tag.equalsIgnoreCase("creationTime")) { 
         earthquake.setTime(myparser.getText()); 
         // time = "" + myparser.getText(); 
         Log.d(LOG_TAG, "Time" + earthquake.getTime()); 
        } 

        if (tag.equalsIgnoreCase("mag")) { 
         myparser.next(); 
         myparser.next(); 
         earthquake.setMagnitude(myparser.getText()); 
         // String smagnitude = myparser.getText(); 
         Log.d(LOG_TAG, "Magnitude" + earthquake.getMagnitude()); 
        } 

        if (tag.equalsIgnoreCase("event")) { 
         earthquakes.add(earthquake); 
        } 

        break; 
      } 
      eventType = myparser.next(); 
     } 

    } catch (XmlPullParserException e) { 

     Log.e("QueryUtils", "Problem parsing the earthquake XML results", e); 
    } 

    // Return the list of earthquakes 
    return earthquakes; 
} 
+0

非常感謝!我知道我的代碼背後的邏輯是錯誤的,你的更有道理:D儘管如此,即使在將代碼改爲建議之後,閱讀日誌我也只能得到空值,除了url,也許我正在使用xmlpullparser的方法不正確的..讓我感到厭煩的是getAttributeValue()方法返回一些東西,而getText()總是爲空。但坦克你再幫助一個陌生人瞭解閱讀xmls的基礎知識:D – Hrothgah

+0

@Hrothgah,你可以在你的問題中更新你的最新代碼..? –

+0

從您的建議開始,我設法解決了這個問題。 我對parser.next()方法的工作原理做了一個錯誤的假設,我認爲當「遊標」位於開始標記 時,您可以閱讀簡單地調用parser.getText()方法的文本;相反,我必須進一步將光標放在文本元素上才能讀取它。 另外,但我不知道是否這是特定的xml特有的東西,在結束標記後,next()方法返回一個文本(「/ n」),所以當調用getName()方法返回null 。 – Hrothgah