I have a class named ExampleHandler extends from DefaultHandler
.
This class reads data from an external xml file (on the web) the structure of this xml file is :
<resultsSet>
<result>
<title>WinRANI Web Services!</title>
<nom>DADI</nom>
<prenom>Morad</prenom>
<adresse>DANS MES REVES</adresse>
</result>
...
</resultsSet>
I've created a class with the same structure of this xml file called ParsedExampleDataSet
(it has getters and setters).
I've also created an ArrayList
which will contain all the 'result' objects but the problem is that when the handler reads all the objects, all items in the ArrayList
are the same.
Here is my code :
package com.example.helloandroid;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_resultset = false;
private boolean in_result = false;
private boolean in_title = false;
private boolean in_nom = false;
private boolean in_prenom = false;
private boolean in_adresse = false;
private boolean in_tel = false;
private boolean in_fax = false;
private boolean in_lon = false;
private boolean in_lat = false;
private boolean in_description = false;
private boolean in_infos = false;
private test t;
private int currentIndex = 0;
ParsedExampleDataSet[] p = new ParsedExampleDataSet[5];
private ArrayList<ParsedExampleDataSet> myParsedExampleDataSetList = new ArrayList<ParsedExampleDataSet>();
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
private ParsedExampleDataSet s1;
private ParsedExampleDataSet s2;
private ParsedExampleDataSet s3;
private ParsedExampleDataSet s4;
private ParsedExampleDataSet s5;
// ===========================================================
// Getter & Setter
// ===========================================================
public ArrayList<ParsedExampleDataSet> getParsedData() {
return this.myParsedExampleDataSetList;
}
// ===========================================================
// Methods
// ===========================================================
@Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
@Override
public void endDocument() throws SAXException {
// Nothing to do
}
/** Gets be called on opening tags like:
* <tag>
* Can provide attribute(s), when xml was like:
* <tag attribute="attributeValue">*/
@Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (localName.equals("resultset")) {
this.in_resultset = true;
}else if (localName.equals("result")) {
this.in_result = true;
}else if (localName.equals("title")) {
this.in_title = true;
}else if (localName.equals("nom")) {
// Extract an Attribute
//String attrValue = atts.getValue("thenumber");
//int i = Integer.parseInt(attrValue);
//myParsedExampleDataSet.setExtractedInt(i);
this.in_nom = true;
}else if (localName.equals("prenom")) {
this.in_prenom = true;
}else if (localName.equals("tel")) {
this.in_tel = true;
}else if (localName.equals("fax")) {
this.in_fax = true;
}else if (localName.equals("lon")) {
this.in_lon = true;
}else if (localName.equals("lat")) {
this.in_lat = true;
}else if (localName.equals("description")) {
this.in_description = true;
}else if (localName.equals("infos")) {
this.in_infos = true;
}
}
/** Gets be called on closing tags like:
* </tag> */
@Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("resultset")) {
this.in_resultset = false;
}else if (localName.equals("result")) {
this.in_result = false;
myParsedExampleDataSetList.add(myParsedExampleDataSet);
}else if (localName.equals("title")) {
this.in_title = false;
}else if (localName.equals("nom")) {
// Nothing to do here
this.in_nom = false;
}else if (localName.equals("prenom")) {
this.in_prenom = false;
}else if (localName.equals("tel")) {
this.in_tel = false;
}else if (localName.equals("fax")) {
this.in_fax = false;
}else if (localName.equals("lon")) {
this.in_lon = false;
}else if (localName.equals("lat")) {
this.in_lat = false;
}else if (localName.equals("description")) {
this.in_description = false;
}else if (localName.equals("infos")) {
this.in_infos = false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
@Override
public void characters(char ch[], int start, int length) {
if(this.in_title){
myParsedExampleDataSet.setExtractedTitle(new String(ch, start, length));
}else 开发者_运维知识库if (this.in_nom){
myParsedExampleDataSet.setExtractedNom(new String(ch,start, length));
}else if (this.in_prenom){
myParsedExampleDataSet.setExtractedPrenom(new String(ch,start, length));
}else if (this.in_tel){
myParsedExampleDataSet.setExtractedTel(new String(ch,start, length));
}else if (this.in_fax){
myParsedExampleDataSet.setExtractedFax(new String(ch,start, length));
}else if (this.in_lon){
myParsedExampleDataSet.setExtractedLon(new String(ch,start, length));
}else if (this.in_lat){
myParsedExampleDataSet.setExtractedLat(new String(ch,start, length));
}else if (this.in_description){
myParsedExampleDataSet.setExtractedDescription(new String(ch,start, length));
}else if (this.in_infos){
myParsedExampleDataSet.setExtractedInfos(new String(ch,start, length));
}
}
}
My xml file also has some other fields.
This is a common misunderstanding with Java. You have to remember that java treats all non-primitives as pointers. In your case, you are new-ing the data container object only once. Therefore when you call your setters and getters you are always affecting the same object which you add multiple times to the array.
You can fix this issue by newing a new container (ParsedExampleDataSet) each time you add a new set of entries to it.
else if (localName.equals("result")) {
this.in_result = true;
myParsedExampleDataSet = new ParsedExampleDataSet();
}
Also remember that the SAXParser can call characters(..) multiple times per field depending on what is in the field. So you might want to concatenate the value you get from characters to what you already have for that field.
if(this.in_title){
String value = myParsedExampleDataSet.getExtractedTitle();
value += new String(ch, start, length)
myParsedExampleDataSet.setExtractedTitle(value);
}
精彩评论