Android - 使用 SAXParser 的通用 XML 解析器

标签 android xml feed gdata-api saxparser

我需要编写一个 XML 解析类,我可以在我的 Android 应用程序中重用它,据我所知,SAXParser 是移动应用程序的最佳选择。我正在使用本指南:

http://www.jondev.net/articles/Android_XML_SAX_Parser_Example

我希望解析的文档类型是来自 Blogger GData API 的提要 - 例如:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;CUIGRnc4fyp7ImA9Wx9SEEg.&quot;'>
    <id>tag:blogger.com,1999:user-464300745974.blogs</id>
    <updated>2010-11-29T17:58:47.937Z</updated>
    <title>Tim's Blogs</title>
    <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/blogs'/>
    <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/blogs'/>
    <link rel='alternate' type='text/html' href='http://www.blogger.com/profile/blogid'/>
    <author>
        <name>Tim</name>
        <uri>http://www.blogger.com/profile/blogid</uri>
        <email>noreply@blogger.com</email>
    </author>
    <generator version='7.00' uri='http://www.blogger.com'>Blogger</generator>
    <openSearch:totalResults>2</openSearch:totalResults>
    <openSearch:startIndex>1</openSearch:startIndex>
    <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
    <entry gd:etag='W/&quot;DUIBQHg-cCp7ImA9Wx9TF0s.&quot;'>
        <id>tag:blogger.com,1999:user-464300745974.blog-blogid</id>
        <published>2010-06-22T10:59:38.603-07:00</published>
        <updated>2010-11-26T02:32:31.658-08:00</updated>
        <title>Application Testing Blog</title>
        <summary type='html'>This blog is for testing the Android application.</summary>
        <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/blogs/blogid'/>
        <link rel='alternate' type='text/html' href='http://devrum.blogspot.com/'/>
        <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devrum.blogspot.com/feeds/posts/default'/>
        <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/posts/default'/>
        <link rel='http://schemas.google.com/blogger/2008#template' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/template'/>
        <link rel='http://schemas.google.com/blogger/2008#settings' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/settings'/>
        <author>
            <name>Tim</name>
            <uri>http://www.blogger.com/profile/blogid</uri>
            <email>noreply@blogger.com</email>
        </author>
    </entry>
    <entry gd:etag='W/&quot;C08HRXo4eSp7ImA9Wx9TE0o.&quot;'>
        <id>tag:blogger.com,1999:user-464300745974.blog-515600026106499737</id>
        <published>2010-06-22T10:59:00.328-07:00</published>
        <updated>2010-11-21T12:37:14.431-08:00</updated>
        <title>Development Blog</title>
        <summary type='html'>etc</summary>
        <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/blogid/blogs/515600026106499737'/>
        <link rel='alternate' type='text/html' href='http://rumdev.blogspot.com/'/>
        <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rumdev.blogspot.com/feeds/posts/default'/>
        <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='http://www.blogger.com/feeds/515600026106499737/posts/default'/>
        <link rel='http://schemas.google.com/blogger/2008#template' type='application/atom+xml' href='http://www.blogger.com/feeds/515600026106499737/template'/>
        <link rel='http://schemas.google.com/blogger/2008#settings' type='application/atom+xml' href='http://www.blogger.com/feeds/515600026106499737/settings'/>
        <author>
            <name>Tim</name>
            <uri>http://www.blogger.com/etc</uri>
            <email>noreply@blogger.com</email>
        </author>
    </entry>
</feed>

我需要像上面那样从提要中解析博客 ID 和帖子 ID。从我在 SAX 上找到的任何示例来看,它们根本不是通用的。我想写一个可重用的,你有什么我可以相应地修改 SAXParser 的例子吗?

最佳答案

SAX 解析器是事件驱动的解析器。您为每种类型的 XML 节点(开始元素、结束元素、属性、文本等)编写一个处理程序,然后解析器迭代 XML 文档并将 SAX 事件发送给您(= 处理程序中的方法被调用)。

在您的特定情况下,您正在寻找两个节点序列:

  1. <feed><id>
  2. <feed><entry><id>

因此您必须在处理程序中存储一些状态信息以了解您的位置。这是代码(我自己没有尝试过,你必须调试它):

public class DataHandler extends DefaultHandler {

    private Feed feed;
    private Entry currentEntry;
    private boolean isId = false;

    public Feed getFeed() {
        return feed;
    }

    @Override
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        if (localName.equals("feed")) {
            feed = new Feed();
        } else if (localName.equals("entry")) {
            currentEntry = new Entry();
        } else if (localName.equals("id")) {
            isId = true;
        }
    }

    @Override
    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
        if (localName.equals("feed")) {
            // </feed> - do nothing, it's the end
        } else if (localName.equals("entry")) {
            // </entry> - save current entry and reset variable
            feed.entries.add(currentEntry);
            currentEntry = null;
        } else if (localName.equals("id")) {
             isId = false;
        }
    }

    @Override
    public void characters(char ch[], int start, int length) {
        if(!isId) return;

        String chars = new String(ch, start, length);
        chars = chars.trim();

        if (currentEntry != null) {
            currentEntry.id = chars;
        } else {
            feed.id = chars;
        }
    }

    private class Feed {
        public String id;
        public List<Entry> entries = new ArrayList<Entry>();
    }

    private class Entry {
        public String id;
    }
}

关于Android - 使用 SAXParser 的通用 XML 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5143628/

相关文章:

android - 如何在 Google Drive SDK v2 中定义文件条目是文件还是文件夹?

android - glCheckFramebufferStatus 返回 36054 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

android - 如何在android中访问ZLIB库方法?

django - 如何禁用 django feed 中的自动转义?

html - HTML YouTube显示所有视频?

android - @android资源ID

objective-c - 从 NSWebView 获取 XML

xml - 我的 XPATH 表达式无法正常工作

swift - 在 swift 中解析 XML 失败并出现 nil 错误

javascript - Rss feed 项目被多次拉入