Android XML解析器仅从Feed中检索第一项

时间:2015-03-14 02:48:33

标签: android xml android-xmlpullparser

我创建了一个小应用,可以将BBC f1新闻Feed读入Android并显示在ListView中。我按照Android Developer Tutorial创建了以下解析函数。

items ArrayList返回活动时,它只有一个项目,即最新的新闻报道。当我记录

通过异步调用成功检索数据后调用这些函数。在倒数第二行,输出标题与返回的数组项相同。

我已将logcat输出发布到pastebin here

RSS结构

<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        // unrequired tags (title, description, lang etc)
        <item>
            <title></title>
            <description></description>
            <link></link>
            <guid isPermaLink="false"></guid>
            <pubDate></pubDate>
            <media:thumbnail  />
            <media:thumbnail  />
        </item>
        <item>
            <title></title>
            <description></description>
            <link></link>
            <guid isPermaLink="false"></guid>
            <pubDate></pubDate>
            <media:thumbnail  />
            <media:thumbnail  />
        </item>
    </channel>
</rss>

阅读Feed功能

private static ArrayList<BBCItem> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    //Log.d("read feed", "");
    ArrayList<BBCItem> items = new ArrayList();

    parser.require(XmlPullParser.START_TAG, ns, "rss");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        // Starts by looking for the channel tag
        if (name.equals("channel")) {
            // navigate to the item tag here
            parser.require(XmlPullParser.START_TAG, ns, "channel");
            while (parser.next() != XmlPullParser.END_TAG){
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                name = parser.getName();
                if (name.equals("item")){
                    items.add(bbcReadEntry(parser));
                }
                else {
                    skip(parser);
                }
            }
        } else {
            skip(parser);
        }
    }
    return items;
}

阅读单个Feed项

public static BBCItem bbcReadEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "item");
    String title = null;
    String description = null;
    String url = null;
    String pubDate = null;
    String thumbnailURL = null;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("title")) {
            title = readString(parser, "title");
        } else if (name.equals("description")) {
            description = readString(parser, "description");
        } else if (name.equals("link")) {
            url = readString(parser, "link");
        } else if (name.equals("pubDate")) {
            pubDate = readString(parser, "pubDate");
        } else if (name.equals("media:thumbnail")) {
            //thumbnailURL = readThumbnail(parser);
            thumbnailURL = "http://news.bbcimg.co.uk/media/images/81615000/jpg/_81615988_nicorosberg.jpg";
        }
        else {
            skip(parser);
        }
    }
    Log.d("News item title", title);
    return new BBCItem(title, description, url, pubDate, thumbnailURL);
}

任何帮助非常感谢

由于

3 个答案:

答案 0 :(得分:1)

在这里处理某些事情时,我遇到了几乎相同的问题。我试图在rss feed xml文件中解析xml。同样的事情发生了,我只得到了第一个“项目”。我还在考虑将xml转换为json,更容易将其作为json处理。但我终于设法让它与xml文件一起工作,而没有与json的交谈。这里出现的问题是没有END_TAG的链接,就像我的情况一样,这导致了问题:

<enclosure url="http:/blabla....mp3" length="123456" type="audio/mpeg" />

在您的情况下,这可能会导致同样的问题:

<media:thumbnail  />

在关注此google文档页面https://developer.android.com/training/basics/network-ops/xml.html之后,我在获取“url”属性后,在获取“url”后直接调用方法“skip(parser)”,进行了大量的测试和头脑攻击我解决了这个问题属性值。这一行解决了我的问题。我假设解析器然后退出该TAG并继续其余的。希望它有所帮助。

答案 1 :(得分:1)

好的,我在尝试解析Scientific American技术RSS提要时遇到了类似的问题。在Android开发人员文档中,readFeed()方法如下所示:

// Program 6.7 Find all the words
#define __STDC_WANT_LIB_EXT1__ 1                           // Make optional versions of functions available
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

int main(void)
{
  char delimiters[] = " \".,;:!?)(";                       // Prose delimiters
  char buf[100];                                           // Buffer for a line of keyboard input
  char str[1000];                                          // Stores the prose to be tokenized
  char* ptr = NULL;                                        // Pointer used by strtok_s()
  str[0] = '\0';                                           // Set 1st character to null

  size_t str_len = sizeof(str);
  size_t buf_len = sizeof(buf);
  printf("Enter some prose that is less than %d characters.\n"
          "Terminate input by entering an empty line:\n", str_len);

  // Read multiple lines of prose from the keyboard
  while(true)
  {
    gets_s(buf, buf_len);                                  // Read a line of input
    if(!strnlen_s(buf, buf_len))                           // Empty line ends input
      break;

    if(strcat_s(str, str_len, buf))                        // Concatenate the line with str
    {
      printf("Maximum permitted input length exceeded.");
      return 1;
    }
  }
  printf("The words in the prose that you entered are:\n", str);

  // Find and list all the words in the prose
  unsigned int word_count = 0;
  char * pWord = strtok_s(str, &str_len, delimiters, &ptr);  // Find 1st word
  if(pWord)
  {
    do
    {
      printf("%-18s", pWord);
      if(++word_count % 5 == 0)
        printf("\n");
      pWord = strtok_s(NULL, &str_len, delimiters, &ptr);    // Find subsequent words
    }while(pWord);                                           // NULL ends tokenizing
    printf("\n%u words found.\n", word_count);
  }
  else
    printf("No words found.\n");

  return 0;
}

我的代码只返回RSS提要中第一项的原因是(在记录条目“entries.add(readEntry(parser));”之后,它到达RSS项目的末尾进入并命中线:

private List readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List entries = new ArrayList();

parser.require(XmlPullParser.START_TAG, ns, "feed");
while (parser.next() != XmlPullParser.END_TAG) {
    if (parser.getEventType() != XmlPullParser.START_TAG) {
        continue;
    }
    String name = parser.getName();
    // Starts by looking for the entry tag
    if (name.equals("entry")) {
        entries.add(readEntry(parser));
    } else {
        skip(parser);
    }
}
return entries;}

这实际上终止了RSS解析,然后点击“返回条目”;返回条目ArrayList的行,其中包含一个项目。

要修复它(至少它对我有用),只需将“END_TAG”修改为“END_DOCUMENT”即可完美运行。

while (parser.next() != XmlPullParser.END_TAG) {

我只是希望这可以帮助某人,因为我整天都在讨论这个问题:-)祝你好运XML解析。

答案 2 :(得分:0)

我从未设法让这个工作充分。相反,我将XML字符串转换为JSON并对其进行操作(我感觉更舒服)。

This answer是我将它从XML转换为JSON的方式。