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 の構文解析は、実にきちんとした仕事です。Android で簡単に使用できる非常に優れたライブラリSimple XMLがあります。優れたチュートリアルを持つ注釈ベースのライブラリです。最良のことは、XML から POJO を直接返すことです。パフォーマンスに関しては、優れています。

必要なのは、XML 用の注釈ベースの POJO を作成することだけです (サイトのチュートリアルを参照してください)。serializer.read(pojoClassType, xmlStr)POJO のオブジェクトを取得するために使用します。

Java Genericsまた、概念を使用して、すべての XML ファイルを読み取る一般化されたメソッドを 1 つだけ作成することもできます。お気に入り、

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


}

QuestionsHandler

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 に答える