用xmlpullparser写入Xml文件夹

问题描述:

我是编程中的新手,为了更好地提高我对android中解析xml的理解,我试图从web服务中获取一些关于地震的数据。我已经阅读了*和其他教程中的所有相关主题,但是我的代码中存在错误。 下面是从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

你的方法的问题是你每次在你的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