Этот код делает неверное предположение, что метод characters
будет вызываться только один раз между вызовами тега startElement
и endElement
.
Вместо логики для установки значений вДля метода characters
необходимо инициализировать буфер в методе startElement
, собрать символы в буфер в методе characters
, а затем выполнить назначения и очистить буфер в методе endElement
.
РЕДАКТИРОВАТЬ:
На самом деле, в вашем коде было несколько других проблем ...
Вы установили setMobilePhone и setWorkPhone в своем классе модели, устанавливая поле homePhone... Неизбежный риск, когда вы копируете-модифицируете код.
И ваш обработчик создавал только один результат, переписал бы и вернул только последний в файле.
У меня естьпоиграл с ним, изменил некоторые методы больше на стандартное именование Java, а также изменил некоторые xml на CamelCase.
Пересмотренный XML:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<PhoneBook>
<PhoneBookEntry>
<FirstName>John</FirstName>
<LastName>Connor</LastName>
<Address>5,Downing Street</Address>
<Phone loc="home">9875674567</Phone>
<Phone loc="work">9875674567</Phone>
<Phone loc="mobile">78654562341</Phone>
</PhoneBookEntry>
<PhoneBookEntry>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<Address>6,Downing Street</Address>
<Phone loc="home">678-56-home</Phone>
<Phone loc="work">678-59-work</Phone>
<Phone loc="mobile">678-85-mobile</Phone>
</PhoneBookEntry>
</PhoneBook>
Пересмотренный ParsedExampleDataSet:
public class ParsedExampleDataSet {
private String firstName = null;
private String lastName =null;
private String address =null;
private String homePhone =null;
private String workPhone =null;
private String mobilePhone =null;
//Firstname
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
//Lastname
public String getLastName(){
return lastName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
//address
public String getAddress(){
return address;
}
public void setAddress(String Address){
this.address =Address;
}
public void setHomePhone(String homePhone){
this.homePhone =homePhone;
}
public void setWorkPhone(String homePhone){
this.workPhone =homePhone;
}
public void setMobilePhone(String homePhone){
this.mobilePhone =homePhone;
}
public String toString(){
return "firstName: " + this.firstName + "\n" + "lastName=: " + this.lastName + "\n" + "address: " + this.address + "\n" + "homePhone: " + this.homePhone + "\n" + "workPhone: " + this.workPhone + "\n" + "mobilePhone: " + this.mobilePhone;
}
}
И обработчик, который выполняет синтаксический анализ:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
public class ExampleHandler extends DefaultHandler {
// ===========================================================
// Fields
// ===========================================================
private boolean in_homePhone = false;
private boolean in_workPhone = false;
private boolean in_mobilePhone = false;
private StringBuffer stringBuffer;
private List<ParsedExampleDataSet> myParsedExampleDataSets;
private ParsedExampleDataSet myParsedExampleDataSet;
// ===========================================================
// Methods
// ===========================================================
public List<ParsedExampleDataSet> getParsedData() {
return myParsedExampleDataSets;
}
@Override
public void startDocument() throws SAXException {
myParsedExampleDataSets = new ArrayList<ParsedExampleDataSet>();
stringBuffer = new StringBuffer();
}
@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 (qName.equals("PhoneBookEntry")) {
myParsedExampleDataSet = new ParsedExampleDataSet();
}
if (qName.equals("Phone")) {
String phoneLocation = atts.getValue("loc");
if (phoneLocation.equals("home")) {
this.in_homePhone = true;
} else if (phoneLocation.equals("work")) {
this.in_workPhone = true;
} else if (phoneLocation.equals("mobile")) {
this.in_mobilePhone = true;
}
}
}
/**
* Gets be called on closing tags like:
* </tag>
*/
@Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
String result = stringBuffer.toString();
stringBuffer.setLength(0);
if (in_homePhone) {
myParsedExampleDataSet.setHomePhone(result);
in_homePhone = false;
}
else if (in_mobilePhone) {
myParsedExampleDataSet.setMobilePhone(result);
in_mobilePhone = false;
}
else if (in_workPhone) {
myParsedExampleDataSet.setWorkPhone(result);
in_workPhone = false;
}
else if (qName.equals("FirstName")) {
myParsedExampleDataSet.setFirstName(result);
}
else if (qName.equals("LastName")) {
myParsedExampleDataSet.setLastName(result);
}
else if (qName.equals("Address")) {
myParsedExampleDataSet.setAddress(result);
}
else if (qName.equals("PhoneBookEntry")) {
myParsedExampleDataSets.add(myParsedExampleDataSet);
}
}
/**
* Gets be called on the following structure:
* <tag>characters</tag>
*/
@Override
public void characters(char ch[], int start, int length) {
stringBuffer.append(new String(ch, start, length));
}
}
Он помещает некоторые вероятные нежелательные пробелы в поля, но я подозреваю, что вы можете выяснить, как его обрезать.
Вызывая его, вы получаете список, а не один объект, но, помимо этого, ваш вызывающий код не должен слишком сильно меняться.Я не пытался работать с этим, так как я не делаю ничего этого на Android.