在Android中遇到XmlPullParser卡住了

3

经过多个小时的搜索和调试,我仍然卡在同一个地方,而且Eclipse也没有帮助我。

我试图解析this rss feed

这非常简单。连接已建立并将InputStream转换为String,这很好运行。

当我尝试解析获得的String时,我没有错误或警告,但我尝试获取的值为空。以下是XML处理过程:

public class XmlOperations {
private static final String ns = null;

public List parse(String in) throws XmlPullParserException, IOException {
    try {

        XmlPullParser parser = Xml.newPullParser();
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(new StringReader(in));
        parser.nextTag();
        return readFeed(parser);
    } finally {
        // 
    }
}

private List readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    List entries = new ArrayList();
    // first xml balise
    parser.require(XmlPullParser.START_TAG, ns,"rss"); 
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        Log.w(TAG, name); // output channel the first time
        // Starts by looking for the item tag
        if (name.equals("item")) {
            **Log.w(TAG, "Never get in here" )**
          entries.add(readEntry(parser));
        } else {
            skip(parser);
            Log.w(TAG, "lala");
        }
    }  
    return entries;
}



// Parses the contents of an item. If it encounters a title, description, or link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the tag.
private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "item");
    String title = null;
    String description = null;
    String link = null;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("title")) {
            title = readTitle(parser);
        } else if (name.equals("description")) {
            description = readDescription(parser);
        } else if (name.equals("link")) {
            link = readLink(parser);
        } else {
            skip(parser);
        }
    }
    return new Entry(title, description, link);
}

// Processes title tags in the feed.
private String readTitle(XmlPullParser parser) throws IOException, XmlPullParserException {
    parser.require(XmlPullParser.START_TAG, ns, "title");
    String title = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "title");
    return title;
}

// Processes link tags in the feed.
private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {
    parser.require(XmlPullParser.START_TAG, ns, "link");
    String link = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "link");
    return link;
}

// Processes summary tags in the feed.
private String readDescription(XmlPullParser parser) throws IOException, XmlPullParserException {
    parser.require(XmlPullParser.START_TAG, ns, "description");
    String description = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "description");
    //Log.d("vALUE = ", summary);
    return description;
}

// For the tags title and description, extracts their text values.
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
    String result = "";
    if (parser.next() == XmlPullParser.TEXT) {
        result = parser.getText();
        parser.nextTag();
    }
    return result;
}

private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
    if (parser.getEventType() != XmlPullParser.START_TAG) {
        throw new IllegalStateException();
    }
    int depth = 1;
    while (depth != 0) {
        switch (parser.next()) {
        case XmlPullParser.END_TAG:
            depth--;
            break;
        case XmlPullParser.START_TAG:
            depth++;
            break;
        }
    }
 }

我猜错误在其中一个解析方法中。

在另一个类中,我有这个:

XmlOperations xml = new XmlOperations();
        try {
            entrieses = xml.parse(result);
            String lol = null;
            for(Entry item : entrieses) {
                //Toast.makeText(getApplicationContext(), item.title, Toast.LENGTH_SHORT).show();
                lol = item.link.toString();
            }
            tv.setText("Pin " + lol + " gouin");

entreses是一个Entry列表。但仍然等于null :(

编辑:通过日志记录,我有 channel lala 就这些


你能展示一下输出的样例吗?最好引用一些当前的RSS订阅数据,以防其消失或更改。 - itsbruce
LogCat 中没有错误或警告的输出。TextView 的输出是 Pin null gouin。 - Freego
你可以尝试设置断点来检查你的 entries.add 是否添加了解析的项。或者你可以简单地添加一些 logcat 输出来记录解析器正在做什么。 - dumbfingers
好的,伙计们,我想你们理解我的意思了。当我登录readFeed方法时,我的第一项是<channel>,所以进入skip(parser)方法,但是当我应该迭代到下一个xml项时,它没有进行。我会修改我的代码让你们看看。 - Freego
2个回答

1

我终于找到了答案。 我的代码是正确的,但我的XML理解有误。 XML如下:

<rss>
    <channel>
        <item>
            <link> </link>
            <title> </title>
        </item>
    </channel>
</rss>

我的代码进入了一个频道,然后是下一个频道,但它不存在。 在我的reedFeed()函数中的循环之前,我只需要添加parser.Next(),以便通过频道标签并直接进入项目标签。 现在它可以工作了 :)


0

我认为你的readFeed()函数中的代码行应该是while (parser.next() != XmlPullParser.END_DOCUMENT) {而不是while (parser.next() != XmlPullParser.END_TAG) {,否则它会很快返回。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接