1

您好,我正在制作一个从 Wiki 提取一些数据的 Android 应用程序,起初我计划寻找一种解析 HTML 的方法,但有人向我指出,XML 会更容易一起工作。现在我被困在试图找到一种正确解析 XML 的方法。我正在尝试从以下网址解析:

http://zelda.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Category:Games&cmlimit=500&format=xml

我正在尝试将每个游戏的标题放入一个字符串数组中,但遇到了一些麻烦。我没有我正在尝试的代码示例,它是使用 xmlpullparser。每次我尝试用它做任何事情时,我的应用程序都会崩溃。将 XML 保存在本地并从那里解析会更好吗?或者我可以从网址出发吗?以及如何将其正确解析为字符串数组?请帮助我,感谢您花时间阅读本文。

如果您需要查看代码或任何我可以在今晚晚些时候获得的东西,我现在不在我的电脑附近。谢谢你。

4

1 回答 1

3

每当您发现自己为简单格式(例如示例中的格式)编写解析器代码时,您几乎总是在做错事并且没有使用合适的框架。

例如 - android.saxSDK 中包含的包中有一组用于解析 XML 的简单帮助程序,而您发布的示例恰好可以像这样轻松解析:

public class WikiParser {
    public static class Cm {
        public String mPageId;
        public String mNs;
        public String mTitle;
    }
    private static class CmListener implements StartElementListener {
        final List<Cm> mCms;
        CmListener(List<Cm> cms) {
            mCms = cms;
        }
        @Override
        public void start(Attributes attributes) {
            Cm cm = new Cm();
            cm.mPageId = attributes.getValue("", "pageid");
            cm.mNs = attributes.getValue("", "ns");
            cm.mTitle = attributes.getValue("", "title");
            mCms.add(cm);
        }
    }
    public void parseInto(URL url, List<Cm> cms) throws IOException, SAXException {
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        try {
            parseInto(new BufferedInputStream(con.getInputStream()), cms);
        } finally {
            con.disconnect();
        }
    }
    public void parseInto(InputStream docStream, List<Cm> cms) throws IOException, SAXException {
        RootElement api = new RootElement("api");
        Element query = api.requireChild("query");
        Element categoryMembers = query.requireChild("categorymembers");
        Element cm = categoryMembers.requireChild("cm");
        cm.setStartElementListener(new CmListener(cms));
        Xml.parse(docStream, Encoding.UTF_8, api.getContentHandler());
    }
}

基本上,这样调用:

WikiParser p = new WikiParser();
ArrayList<WikiParser.Cm> res = new ArrayList<WikiParser.Cm>();
try {
    p.parseInto(new URL("http://zelda.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Category:Games&cmlimit=500&format=xml"), res);
} catch (MalformedURLException e) {
} catch (IOException e) {
} catch (SAXException e) {}

编辑:这就是您创建的List<String>方式:

public class WikiParser {
    private static class CmListener implements StartElementListener {
        final List<String> mTitles;
        CmListener(List<String> titles) {
            mTitles = titles;
        }
        @Override
        public void start(Attributes attributes) {
            String title = attributes.getValue("", "title");
            if (!TextUtils.isEmpty(title)) {
                mTitles.add(title);
            }
        }
    }
    public void parseInto(URL url, List<String> titles) throws IOException, SAXException {
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        try {
            parseInto(new BufferedInputStream(con.getInputStream()), titles);
        } finally {
            con.disconnect();
        }
    }
    public void parseInto(InputStream docStream, List<String> titles) throws IOException, SAXException {
        RootElement api = new RootElement("api");
        Element query = api.requireChild("query");
        Element categoryMembers = query.requireChild("categorymembers");
        Element cm = categoryMembers.requireChild("cm");
        cm.setStartElementListener(new CmListener(titles));
        Xml.parse(docStream, Encoding.UTF_8, api.getContentHandler());
    }
}

进而:

WikiParser p = new WikiParser();
ArrayList<String> titles = new ArrayList<String>();
try {
    p.parseInto(new URL("http://zelda.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Category:Games&cmlimit=500&format=xml"), titles);
} catch (MalformedURLException e) {
} catch (IOException e) {
} catch (SAXException e) {}
于 2012-05-26T17:20:17.173 回答