Android XML Pull Parsing while循环不起作用

时间:2014-03-17 21:50:49

标签: android xml-parsing xmlpullparser

我有一些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"。并不总是有四种选择,可能会有更多或更少,这就是为什么我需要能够循环它。

2 个答案:

答案 0 :(得分:0)

也许您省略标签的开头和结尾这一事实。
也许这会奏效:

 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);
}

答案 1 :(得分:0)

我只是避免一起查找"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并不想添加到问题对象中。后来,当我返回一个对象时,我没有得到问题列表。我确定这很容易解决。