我有一个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并使用数据实例化一个问题对象。
有人能告诉我需要改变什么吗?
Here's the tutorial我一直在努力调整
答案 0 :(得分:2)
解析XML实际上是一项非常整洁的工作。有一个非常好的库Simple XML,我们可以在Android中轻松使用它。它是基于注释的库,有很好的教程。最好的是它直接从您的XML&amp;中返回一个POJO。在性能方面,它是好的。
您需要做的就是为您的XML创建基于注释的POJO(请参阅网站上的教程)。使用serializer.read(pojoClassType, xmlStr)
获取POJO的对象。
此外,您可以使用Java Generics
概念仅使一个通用方法读取每个XML文件。等,
public <T> T parseXML(Class<T> pojoType, String xmlStr){
//your code
}
答案 1 :(得分: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>
我按顺序放置游戏 root标记,因为您可以看到,如果您想要多个主题,请使XML有效。
重要提示:我的示例也适用于网址(http://www.macs.hw.ac.uk/~pjbk/quiz/example.xml)。你只需要取消注释即可。
<强> Anserw 强>
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;
}
}
<强> XMLManager 强>
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;
}
}
<强> MyMain 强>
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
希望它有所帮助; - )