2015-10-29 2 views
0

В настоящее время я изучаю Android-программирование, и когда я пытаюсь разобрать XML, я получаю эту ошибку ниже (программа работает нормально, но она только анализирует первую XML-ссылку):Разбор XML в Android (XmlPullParserException)

enter image description here

Вот мой код:

public class RSSActivity extends AppCompatActivity { 

/** 
* List of feeds that has been fetched. 
*/ 
public static ArrayList<RSSFeed> Feeds; 

/** 
* Button for Seattle Times 
*/ 
private Button mSeattleBtn; 

/** 
* Button for ESPN 
*/ 
private Button mESPNBtn; 

/** 
* The layout contains the loading image 
*/ 
private RelativeLayout mProgress; 

/** 
* {@inheritDoc} 
*/ 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_rss); 

    Feeds = new ArrayList<>(); 
    mProgress = (RelativeLayout) findViewById(R.id.loading); 
    mProgress.setVisibility(View.GONE); 

    mSeattleBtn = (Button) findViewById(R.id.seattle_times); 
    mSeattleBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      new DownloadXML().execute("http://www.seattletimes.com/feed/", 
        "http://www.seattletimes.com/seattle-news/feed/", 
        "http://www.seattletimes.com/nation-world/feed/"); 
     } 
    }); 

    mESPNBtn = (Button) findViewById(R.id.espn_btn); 
    mESPNBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      new DownloadXML().execute("http://sports.espn.go.com/espn/rss/news", 
        "http://sports.espn.go.com/espn/rss/nfl/news", 
        "http://sports.espn.go.com/espn/rss/nba/news"); 
     } 
    }); 

} 

/** 
* Async task to fetch the XML from the internet 
*/ 
private class DownloadXML extends AsyncTask<String, Void, String> { 

    /** 
    * The name of the current class, used for Log (debugging) 
    */ 
    private static final String TAG = "DownloadXML"; 

    /** 
    * The content of the xml that has been fetched from the internet 
    */ 
    private String xmlContent; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     xmlContent = ""; 
     mSeattleBtn.setVisibility(View.GONE); 
     mESPNBtn.setVisibility(View.GONE); 
     mProgress.setVisibility(View.VISIBLE); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    protected String doInBackground(String... params) { 

     // set the xml contents to xmlContent 
     //xmlContent = getXMLContent(params[0]); 
     for (String s: params) { 
      xmlContent += getXMLContent(s); 
     } 

     // This will return the xmlContent to the onPostExecute method. 
     return xmlContent; 
    } 

    /** 
    * Perform the actual downloading process of the RSS 
    * file here. 
    * 
    * @param path the url path of the rss feed. 
    * @return the completed download xml file (converted to String) 
    */ 
    private String getXMLContent(String path) { 
     StringBuilder temp = new StringBuilder(); 

     try { 

      // Open the connection 
      URL url = new URL(path); 
      HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
      InputStream inputStream = con.getInputStream(); 
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream); 

      int charToRead; 
      // reading 1000 bytes at a time. 
      char[] input = new char[1000]; 

      // Keep reading the file until there's no more bytes(chars) left to read 
      while(true) { 
       charToRead = inputStreamReader.read(input); 
       if(charToRead <= 0) { 
        break; 
       } 
       temp.append(String.copyValueOf(input, 0, charToRead)); 
      } 

      return temp.toString(); 

     } catch (IOException e) { 
      Log.d(TAG, "Error: " + e.getMessage()); 
     } 

     return null; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     RSSFeed curFeed = null; 
     boolean inItem = false; 
     String value = ""; 

     try { 
      // Instantiate XmlPullParser 
      XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 
      // specify that the code will be supported by XML namespaces 
      factory.setNamespaceAware(true); 
      XmlPullParser parser = factory.newPullParser(); 
      parser.setInput(new StringReader(result)); 
      int event = parser.getEventType(); 

      // Parse the XML content 
      while(event != XmlPullParser.END_DOCUMENT) { 
       String tag = parser.getName(); 

       // Only parse with the starting and ending tag of "item" 
       // and every tags inside it, ignore other tags. 
       switch(event) { 
        case XmlPullParser.START_TAG: 
         // if the begin tag is item which mean 
         // we can begin to to fetch the xml tags we want into our application 
         if(tag.equalsIgnoreCase("item")) { 
          inItem = true; 
          curFeed = new RSSFeed(); 
         } 
         break; 
        case XmlPullParser.TEXT: 
         value = parser.getText(); 
         break; 
        case XmlPullParser.END_TAG: 
         /* 
          while reach the end tag of the current tag 
          if the end tag is title then set it to the current feed title, 
          if the end tag is link then set it to the current feed link, 
          if the end tag is pubdate then set it to the current feed pubdate, 
          if the end tag is item we know that there's no more contents to add 
          to the current feed so we move on to parse another feed. 
         */ 
         if(inItem){ 
          if (tag.equalsIgnoreCase("title")) { 
           curFeed.setTitle(value); 
          } else if (tag.equalsIgnoreCase("link")) { 
           curFeed.setLink(value); 
          } else if (tag.equalsIgnoreCase("pubdate")) { 
           curFeed.setDate(value); 
          } else if (tag.equalsIgnoreCase("item")) { 
           Feeds.add(curFeed); 
           inItem = false; 
          } 
         } 
         break; 
        default: 

       } 

       event = parser.next(); 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     findViewById(R.id.loading).setVisibility(View.GONE); 
     Intent intent = new Intent(RSSActivity.this, FeedListActivity.class); 
     startActivity(intent); 
     finish(); 

    } 
} 
} 

Так как я новичок на все это, может кто-то пожалуйста, объясните мне, что здесь происходит? Похоже, что ошибка исходила из парсера.

EDIT: если я передаю только один параметр Asynctask.execute(), тогда все будет работать нормально.

РЕШЕНИЕ:

Единственное решение теперь обрабатывать каждый URL последовательно, как ответил nikhil.thakkar

Тогда я хотел бы предложить вам обрабатывать каждый URL последовательно ..

+0

Я думаю, что есть проблема с вашим xml. Можете ли вы также вставить xml. –

+0

Ссылки на xml находятся в анонимных классах setOnClickListener() – ln206

+0

Можете ли вы распечатать временную переменную и вставить содержимое здесь в строку. –

ответ

1

Пожалуйста, проверьте метод onPostExecute. Вы получаете доступ к токену, которого нет в файле XML.

+0

Привет, я просто дважды проверял ссылки XML, каждый канал RSS начинался с тега 'item', и в каждом теге' item' есть теги 'link',' title', 'pubdate'. Если это вы имели в виду, или я все еще не понимаю, что вы только что сказали, извините. – ln206

Смежные вопросы