0

我有一个 XML 文件,如下所示:

<questions title="(Some question Category)">
 <question>
  <ask>(Some question)?</ask>
  <answer>(Some answer)</answer>
  <answer correct="true">(Some correct answer)</answer>
  <answer>(Some answer)</answer>
  <answer>(Some answer)</answer>
 </question>
</questions>

我正在使用 SAX 来解析文件。据我所知,所有必需的 SAX 文件都已正确设置。

然后我有一个处理程序类,我查找了如何为稍微不同的 XML 文件编写代码。我尝试为上面的 xml 调整它,这就是我想出的(未完成):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.widget.TextView;

public class QuestionHandler extends DefaultHandler {
    //list for imported product data
    private ArrayList<TextView> theViews;
    //string to track each entry
    private String currQuestion = "";
    //flags to keep track of XML processing
    private boolean isAsk = false;
    private boolean isAnswer = false;
    //context for user interface
    private Context theContext;
    //constructor
    public QuestionHandler(Context cont) {
        super();
        theViews = new ArrayList<TextView>();
        theContext = cont;
    }

    //start of the XML document
    public void startDocument () { Log.i("QuestionHandler", "Start of XML document"); }

    //end of the XML document
    public void endDocument () { Log.i("QuestionHandler", "End of XML document"); }

    //opening element tag
    public void startElement (String uri, String name, String qName, Attributes atts)
    {
        //find out if the element is a question
        if(qName.equals("question"))
        {
            //set ask and answer tag to false
            isAsk = false;
            isAnswer = false;
            //create View item for question display
            TextView questionView = new TextView(theContext);
            questionView.setTextColor(Color.rgb(73, 136, 83));
            //add the attribute value to the displayed text
            String viewText = "Items from " + atts.getValue("name") + ":";
            questionView.setText(viewText);
            //add the new view to the list
            theViews.add(questionView);
        }
        //or if the element is an asked question
        else if(qName.equals("ask"))
            isAsk = true;

        //or if element is an answer
        else if(qName.equals("answer"))
            isAnswer = true;
    }

    //closing element tag
    public void endElement (String uri, String name, String qName)
    {
        if(qName.equals("question"))
        {
            //create a View item for the asked
            TextView askView = new TextView(theContext);
            askView.setTextColor(Color.rgb(192, 199, 95));
            //display the compiled items
            askView.setText(currQuestion);
            //add to the list
            theViews.add(askView);
            //create a View item for the answers
            TextView answersView = new TextView(theContext);
            answersView.setTextColor(Color.rgb(192, 199, 95));
            //display the compiled items
            answersView.setText(currQuestion);
            //add to the list
            theViews.add(answersView);
            //reset the variable for future items
            currQuestion = "";
        }
    }

    //element content
    public void characters (char ch[], int start, int length)
    {
        //string to store the character content
        String currText = "";
        //loop through the character array
        for (int i=start; i<start+length; i++)
        {
            switch (ch[i]) {
            case '\\':
                break;
            case '"':
                break;
            case '\n':
                break;
            case '\r':
                break;
            case '\t':
                break;
            default:
                currText += ch[i];
                break;
            }
        }
        //prepare for the next item
        if(isAsk || isAnswer && currText.length()>0)
            currQuestion += currText+"\n";
    }
    public ArrayList<TextView> getData()
    {
        //take care of SAX, input and parsing errors
        try
        {
            //set the parsing driver
            System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
            //create a parser
            SAXParserFactory parseFactory = SAXParserFactory.newInstance();
            SAXParser xmlParser = parseFactory.newSAXParser();
            //get an XML reader
            XMLReader xmlIn = xmlParser.getXMLReader();
            //instruct the app to use this object as the handler
            xmlIn.setContentHandler(this);
            //provide the name and location of the XML file **ALTER THIS FOR YOUR FILE**
            URL xmlURL = new URL("http://www.macs.hw.ac.uk/~pjbk/quiz/example.xml");
            //open the connection and get an input stream
            URLConnection xmlConn = xmlURL.openConnection();
            InputStreamReader xmlStream = new InputStreamReader(xmlConn.getInputStream());
            //build a buffered reader
            BufferedReader xmlBuff = new BufferedReader(xmlStream);
            //parse the data
            xmlIn.parse(new InputSource(xmlBuff));
        }
        catch(SAXException se) { Log.e("AndroidTestsActivity", 
                "SAX Error " + se.getMessage()); }
        catch(IOException ie) { Log.e("AndroidTestsActivity", 
                "Input Error " + ie.getMessage()); }
        catch(Exception oe) { Log.e("AndroidTestsActivity", 
                "Unspecified Error " + oe.getMessage()); }
        //return the parsed product list
        return theViews;
    }

}

最后,我的 initialiseQuestions() 方法,来自其他工作活动,将提取的 XML 数据分配给问题类(同样,未完成):

private void initialiseQuestions() {
    // TODO Auto-generated method stub

    questions = new Vector<Question>(); //Vector containing our questions

    try
    {
        //create an instance of the QuestionHandler class
        QuestionHandler handler = new QuestionHandler(getApplicationContext());
        //get the string list by calling the public method
        ArrayList<TextView> newViews = handler.getData();
        //convert to an array
        Object[] question = newViews.toArray();
        //loop through the items, creating a View item for each
        for(int i=0; i<question.length; i++)
        {
            //add the next question in the list
            Question q1 = new Question(question[i]);
            q1.addAnswer("Harold Godwin", false);
            q1.addAnswer("Edward the Confessor", false);
            q1.addAnswer("William the Conqueror", true);
            q1.addAnswer("Alfred the Great", false);
            questions.add(q1);
            //mainLayout.addView((TextView)products[i]);
        }

    }
    catch(Exception pce) { Log.e("AndroidTestsActivity", "PCE "+pce.getMessage()); }

我的主要问题是我真的不明白我在做什么/需要在处理程序和 initialiseQuestions 方法中进行更改。我不明白字符串是如何在处理程序中创建的(如果您只需要发回一个字符串数组,为什么还需要 textViews?)而且我不明白如何在 initialiseQuestions 中处理数据。如您所见, initaliseQuestions 方法应采用已解析的 XML 并使用数据实例化问题对象。

有人能告诉我我需要改变什么吗?

这是我一直在尝试调整的教程

4

2 回答 2

2

解析 XML 确实是一项整洁的工作。有一个非常好的库Simple XML,我们可以很容易地在 Android 中使用它。它是基于注释的库,有很好的教程。最好的事情是它直接从您的 XML 中返回一个 POJO,并且在性能方面,这很好。

您需要做的就是为您的 XML 创建一个基于注释的 POJO(请参阅网站上的教程)。用于serializer.read(pojoClassType, xmlStr)获取 POJO 的对象。

您也可以使用Java Generics概念来制作仅一种通用方法来读取每个 XML 文件。喜欢,

public <T> T parseXML(Class<T> pojoType, String xmlStr){
 //your code
} 
于 2012-11-09T05:15:18.117 回答
0

这就是我使用 SAX 使其工作的方式。

我已经为我的调试示例修改了一点你的 XML 文件:

   <game>
    <questions title="History">
        <question>
        <ask>Who won the Battle of Hastings?</ask>
        <answer>Harold Godwinson</answer>
        <answer correct="true">William of Normandy</answer>
        <answer>Edward the Confessor</answer>
        <answer>Harald Hadrada</answer>
        </question>
        <question>
        <ask>French revolution date?</ask>
        <answer>January 10th</answer>
        <answer correct="true">July 14th</answer>
        <answer>September 9th</answer>
        <answer>February 20th</answer>
        </question>
    </questions>
    <questions title="Geography">
        <question>
        <ask>France capital?</ask>
        <answer>Montreal</answer>
        <answer correct="true">Paris</answer>
        <answer>Lyon</answer>
        <answer>Barcelona</answer>
        </question>
    </questions>
</game>

我已经按顺序放置了游戏根标签,如您所见,让 XML 有效,以防您需要多个主题。

重要提示:我的示例也适用于 URL ( http://www.macs.hw.ac.uk/~pjbk/quiz/example.xml )。您只需取消注释即可。

JAVA 类

答案

public class Anserw {

    private String content;
    private boolean isCorrect;

    public Anserw(){}

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public boolean isCorrect() {
        return isCorrect;
    }

    public void setCorrect(boolean isCorrect) {
        this.isCorrect = isCorrect;
    }


}

问题

public class Question {

    private String ask;
    private ArrayList<Anserw> alAnserws;

    public Question(){}


    public String getAsk() {
        return ask;
    }

    public void setAsk(String ask) {
        this.ask = ask;
    }

    public ArrayList<Anserw> getAlAnserws() {
        return alAnserws;
    }

    public void setAlAnserws(ArrayList<Anserw> alAnserws) {
        this.alAnserws = alAnserws;
    }


}

问题处理程序

public class QuestionsHandler extends DefaultHandler{

    private HashMap<String, ArrayList<Question>> hmTitleQuestions;
    private String reading;
    private String currentTitle;
    private Question question;
    private ArrayList<Anserw> alAnserws;
    private ArrayList<Question> alQuestions;
    private Anserw anserw;

    public QuestionsHandler(){
        hmTitleQuestions = new HashMap<>();
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {

        if(qName.equals("questions")){
            currentTitle = attributes.getValue("title");
            alQuestions = new ArrayList<>();
        }
        if(qName.equals("question")){
            question = new Question();
        }
        if(qName.equals("answer")){
            anserw = new Anserw();
            boolean flag = false;
            String correctAttribute = attributes.getValue("correct");
            if(correctAttribute != null){
                if(correctAttribute.equals("true")){
                    flag = true;
                }
            }
            anserw.setCorrect(flag);
        }

    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {

        if(qName.equals("questions")){
            hmTitleQuestions.put(currentTitle, alQuestions);
        }
        if(qName.equals("question")){
            question.setAlAnserws(alAnserws);
            alQuestions.add(question);
        }
        if(qName.equals("ask")){
            question.setAsk(reading);
            alAnserws = new ArrayList<>();
        }
        if(qName.equals("answer")){
            anserw.setContent(reading);
            alAnserws.add(anserw);
        }

    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        reading = new String(ch, start, length);
    }

    public HashMap<String, ArrayList<Question>> getHmTitleQuestions() {
        return hmTitleQuestions;
    }



}

XML管理器

public final class XMLManager {


    public static HashMap<String, ArrayList<Question>> getHmTitleQuestions(){

        HashMap<String, ArrayList<Question>> hmTitleQuestions = null;
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {

            SAXParser parser = factory.newSAXParser();
            /*
            URL url = new URL("http://www.macs.hw.ac.uk/~pjbk/quiz/example.xml");
            HttpURLConnection connexion = (HttpURLConnection) url.openConnection();
            connexion.connect();
            InputSource in = new InputSource(connexion.getInputStream());
            */
            QuestionsHandler qHandler = new QuestionsHandler();
            /*
             *  FROM INTERNET XML
             * 
                parser.parse(in, qHandler);
                hmTitleQuestions = qHandler.getHmTitleQuestions();


            */

            /*
             *  FROM LOCAL XML TO DEBUG
             */
            File file = new File("D:\\Loic_Workspace\\TestGameSAXUrl\\res\\game.xml");
            parser.parse(file,qHandler);
            hmTitleQuestions = qHandler.getHmTitleQuestions();

        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        return hmTitleQuestions;

    }


}

我的主

public class MyMain {

    /**
     * @param args
     */
    public static void main(String[] args) {


        for(String s : XMLManager.getHmTitleQuestions().keySet()){
            ArrayList<Question> alQuestions = XMLManager.getHmTitleQuestions().get(s);
            ArrayList<Anserw> alAnserws = null;
            System.out.println(s);
            for(Question q:alQuestions){
                System.out.println(q.getAsk());
                alAnserws = q.getAlAnserws();
                for(Anserw a:alAnserws){
                    System.out.println("Content anserw : "+a.getContent()+"/"+a.isCorrect());
                }

            }
        }



    }

}

控制台输出

History
Who won the Battle of Hastings?
Content anserw : Harold Godwinson/false
Content anserw : William of Normandy/true
Content anserw : Edward the Confessor/false
Content anserw : Harald Hadrada/false
French revolution date?
Content anserw : January 10th/false
Content anserw : July 14th/true
Content anserw : September 9th/false
Content anserw : February 20th/false
Geography
France capital?
Content anserw : Montreal/false
Content anserw : Paris/true
Content anserw : Lyon/false
Content anserw : Barcelona/false

希望能帮助到你 ;-)

于 2013-02-07T05:08:04.167 回答