我创建了一个小应用,可以将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);
}
任何帮助非常感谢
由于
答案 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的方式。