【问题标题】:can't seem to parse xml?似乎无法解析xml?
【发布时间】:2015-08-15 13:20:42
【问题描述】:

我正在制作一个 Android 应用程序,我想在其中向用户显示他们的作者当天的随机报价。为此,我使用了他们所说的 Quote API。我正在尝试解析这个http://api.theysaidso.com/qod.xml 文件,以便我可以在我的代码中使用他们的作者当天的报价。但由于某种原因,我的 onPostExecute 中的结果参数为空。所以我猜 XML 没有正确解析,或者我没有在我的 ArrayList 中放入正确的值,这是 xmlParser.parse(inputStream) 方法的结果?或者是什么原因导致我的 ArrayList 结果仍然为空?

XML 解析器:

public class XMLParser {

private static final String ns = null;


public List parse(InputStream in) throws XmlPullParserException, IOException {
    try {
        XmlPullParser parser = Xml.newPullParser();
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(in, null);
        parser.nextTag();
        return readResponse(parser);
    } finally {
        in.close();
    }
}

private List readResponse(XmlPullParser parser) throws XmlPullParserException, IOException {
    List quotes = new ArrayList();

    parser.require(XmlPullParser.START_TAG, ns, "response");
    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("quotes")) {
            quotes.add(readEntry(parser));
        } else {
            skip(parser);
        }
    }
    return quotes;
}

public static class Quote{
    public final String quote;
    public final String author;

    private Quote(String quote, String author) {
            this.quote = quote;
            this.author = author;
    }

}

// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the tag.
private Quote readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "quotes");
    String quote = null;
    String author = null;

    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("quote")) {
            quote = readQuote(parser);
        } else if (name.equals("author")) {
            author = readAuthor(parser);
        } else {
            skip(parser);
        }
    }
    return new Quote(quote, author);
}

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

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

// For the tags quote and author, 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;
        }
    }
}

}

我的活动

String url="http://api.theysaidso.com/qod.xml";
    setContentView(R.layout.activity_quotes);
    new DownloadXML().execute(url);

private class DownloadXML extends AsyncTask<String,Void,ArrayList> {

    @Override
    protected ArrayList doInBackground(String... url) {

        ArrayList lijstQuote = new ArrayList();


        try {
            InputStream inputStream = new URL(url[0]).openStream();

            XMLParser xmlParser = new XMLParser();
            lijstQuote =(ArrayList) xmlParser.parse(inputStream);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return lijstQuote;
    }

    protected void onPostExecute(ArrayList result) {

        if (!result.isEmpty()) {
            XMLParser.Quote contents = (XMLParser.Quote) result.get(0);
            TextView quoteTekst = (TextView) findViewById(R.id.quote);
            quoteTekst.setText(contents.quote);

            TextView authorTekst = (TextView) findViewById(R.id.author);
            authorTekst.setText(contents.author);
        }
        else
        {
            TextView quoteTekst = (TextView) findViewById(R.id.quote);
            quoteTekst.setText(R.string.outOfQuotes);

            TextView authorTekst = (TextView) findViewById(R.id.author);
            authorTekst.setText(R.string.authorOutOfQuotes);
        }
    }
}

【问题讨论】:

    标签: android xml


    【解决方案1】:

    非常简单。使用 XML Linq

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string input =
                    "<?xml version=\"1.0\"?>" +
                        "<response>" +
                          "<success>" +
                            "<total>1</total>" +
                          "</success>-<contents>" +
                            "<quotes>" +
                              "<quote>I quote others only to better express myself. </quote>" +
                              "<length>46</length>" +
                              "<author>Michel de Montaigne</author>" +
                              "<tags>humor</tags>" +
                              "<tags>irony</tags>" +
                              "<tags>truth</tags>" +
                              "<tags>tso-funny</tags>" +
                              "<category>funny</category>" +
                              "<id>dfSt40pVwYqH6_y1K_A7iAeF</id>" +
                            "</quotes>" +
                          "</contents>" +
                        "</response>";
    
                XDocument doc = XDocument.Parse(input);
    
                var results = doc.Descendants("quotes").Select(x => new
                {
                    quote = (string)x.Element("quote"),
                    author = (string)x.Element("author")
                }).ToList();
            }
        }
    }
    ​
    

    【讨论】:

    • 这个话题对我也很有用:stackoverflow.com/questions/8897459/…
    • 您可以使用 XmlDocument(如帖子中的内容)或 XDocument(xml linq)来解析 XML。 xml linq 代码需要较少的代码,并且很容易进行大多数类型的解析。您可以使用任何一种方法获得相同的结果。
    • 如果您在每个响应中收到多个引号,您可能需要将 : Descendants("quotes") 更改为 : Descendants("quote")
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多