【问题标题】:Android XML Pull Parsing while loop not workingAndroid XML Pull Parsing while loop not working
【发布时间】:2014-03-17 21:50:49
【问题描述】:

我有一些如下所示的 XML

<question id="0">
  <text>
    Who is the first President of the United States of America?
  </text>
  <image>
    http://upload.wikimedia.org/wikipedia/commons/b/b6/Gilbert_Stuart_Williamstown_Portrait_of_George_Washington.jpg
  </image>
  <choices>
    <choice answer="true">George Washington</choice>
    <choice>Thomas Jefferson</choice>
    <choice>James Monroe</choice>
    <choice>John Adams</choice>
  </choices>
</question>

我正在尝试将其解析为一些对象。目前,我有一个while循环,当解析器检查if"choices"是当前标签时,它会进入并启动while循环以获取所有选择标签并从中生成对象。

QuestionUtil

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;

public class QuestionUtil {

static ArrayList<Question> parseQuestions(InputStream xmlIn) throws XmlPullParserException, IOException {

    XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
    parser.setInput(xmlIn, "UTF-8");

    Question question = null;
    ArrayList<Question> questionList = new ArrayList<Question>();
    Choices choices = null;
    ArrayList<Choices> choiceList = new ArrayList<Choices>();

    int event = parser.getEventType();

    while (event != XmlPullParser.END_DOCUMENT) {

        switch (event) {
        case XmlPullParser.START_TAG:

            if(parser.getName().equals("question")) {

                question = new Question();

                try {
                    question.setId(parser.getAttributeValue(null, "id"));
                }
                catch (NumberFormatException ex) { }

            }

            else if (parser.getName().equals("text")) {
                question.setText(parser.nextText());
            }

            else if (parser.getName().equals("image")) {
                question.setImage(parser.nextText());
            }

            else if (parser.getName().equals("choices")) {

                boolean isCorrect;
                String answer;
                parser.next();

/**** (BELOW) THIS PART IS NOT WORKING PROPERLY ****/
                // parser.getName().equals("choice")
                while ("choice".equals(parser.getName())) {

                    if (parser.getAttributeValue(null, "answer") != null) {
                        isCorrect = true;
                        answer = parser.nextText();
                        choices = new Choices(isCorrect, answer);
                    }
                    else {
                        isCorrect = false;
                        answer = parser.nextText();
                        choices = new Choices(isCorrect, answer);
                    }

                    choiceList.add(choices);
                    parser.next();

                    // Testing purposes
                    Log.d("demo", answer + " " + isCorrect);

                }
/**** (ABOVE) THIS PART IS NOT WORKING PROPERLY ****/

                question.setChoices(choiceList);

            } // END Choices Parsing

            break;

        case XmlPullParser.END_TAG:

            if (parser.getName().equals("question")) {
                questionList.add(question);
                question = null;
            }

            break;

        default:
            break;

        } // END Switch

        event = parser.next();

    } // END While loop

    return questionList;

}

}

谁能帮我弄清楚为什么它不起作用?一旦我有一个if 语句来检查"choices" 标签,我就继续前进,parser.next() 转到下一行,应该是"choice"。并不总是有四个选择,可能或多或少,这就是为什么我需要能够循环通过它。

【问题讨论】:

  • 您不需要在“选择”项的循环中添加case XmlPullParser.START_TAG 吗?
  • 像嵌套的case XmlPullParser.START_TAG: 你的意思是?我想这是可能的,我会研究一下。

标签: android xml-parsing xmlpullparser


【解决方案1】:

也许你忽略了标签的开始和结束是问题所在。
也许这会起作用:

 while ("choice".equals(parser.getName())) {
    if (parser.getEventType()==XmlPullParser.START_TAG) {
        if (parser.getAttributeValue(null, "answer") != null) {
            isCorrect = true;
            answer = parser.nextText();
            choices = new Choices(isCorrect, answer);
        } else {
            isCorrect = false;
            answer = parser.nextText();
            choices = new Choices(isCorrect, answer);
        }
        choiceList.add(choices);
    }
    parser.next();
    // Testing purposes
    Log.d("demo", answer + " " + isCorrect);
}

【讨论】:

  • 我认为它仍然会遍历 choices 的结束标记,因为它处于一个很大的 while 循环中。但我确实在我的代码中尝试过,但由于某种原因,它仍然无法访问循环周期,或者我会通过 Log.d 获得日志信息。
【解决方案2】:

我只是避免一起寻找"choices" 标签,而是像所有其他标签一样找到"choice" 标签。为了使逻辑正常工作,我等待将choicesList 添加到问题对象中,直到在下一个案例中,原始标签的END_TAG 是问题。

else if (parser.getName().equals("choice")) {

                boolean isCorrect;
                String answer;

                if (parser.getAttributeValue(null, "answer") != null) {
                    isCorrect = true;
                    answer = parser.nextText();
                    choices = new Choices(isCorrect, answer);
                }
                else {
                    isCorrect = false;
                    answer = parser.nextText();
                    choices = new Choices(isCorrect, answer);
                }

                choiceList.add(choices);

            } // END Choices Parsing

还有下一个案例:

case XmlPullParser.END_TAG:

            if (parser.getName().equals("question")) {

                // Testing purposes
                Log.d("demo", ">>>" + choiceList.toString());
                question.setChoices(choiceList);
                questionList.add(question);
                question = null;
                choices = null;
                choiceList.clear();

            }

            break;

但由于某种原因,choicesList 不想添加到问题对象中。后来,当我返回一个对象时,我没有得到问题列表。我相信这很容易解决。

【讨论】:

    猜你喜欢
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-27
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    相关资源
    最近更新 更多