Программирование XML парсера в Android (1 часть тут)Рассмотрим конкретный пример. Допустим, нам пришел XML ответ, содержащий имя, фамилию и возраст пользователя:
<person> <firstname>Jack</firstname> <lastname>smith</lastname> <age>28</age> </person>
С помощью этих параметров нужно создать объект класса Person: public class Person{
public String firstName;
public String lastName;
public int age;
} Использование DOM ParserВ библиотека org.w3c.dom можно найти классы, с помощью которых можно разобрать xml, создав документ и сравнив каждый узел с шаблоном. Приведенная ниже функция использует DOM парсер: void parseByDOM(String response) throws ParserConfigurationException, SAXException, IOException{
Person person=new Person();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(response)));
// нормализируем документ
doc.getDocumentElement().normalize();
// получаем корневой узел
NodeList nodeList = doc.getElementsByTagName("person");
Node node=nodeList.item(0);
// узел имеет три дочерних узла
for (int i = 0; i < node.getChildNodes().getLength(); i++) {
Node temp=node.getChildNodes().item(i);
if(temp.getNodeName().equalsIgnoreCase("firstname")){
person.firstName=temp.getTextContent();
}
else if(temp.getNodeName().equalsIgnoreCase("lastname")){
person.lastName=temp.getTextContent();
}
else if(temp.getNodeName().equalsIgnoreCase("age")){
person.age=Integer.parseInt(temp.getTextContent());
}
}
Log.e("person", person.firstName+ " "+person.lastName+" "+String.valueOf(person.age));
} Показаный метод работает, однако для его использования нужно знать структуру разбираемого xml и порядок перечисления узлов. Более гибок в этом плане SAX парсер.
Использование SAX ParserSAX Parser находится в пакете org.xml.sax. В процессе разбора документа SAX генерирует события, для которых программист должен написать обработчики. Создадим класс-потомок основе класса DefaultHandler и переопределим следующие методы:
- startDocument(): Этот метод вызывается при открытии XML документа.
- startElement(String uri, String localName, String qName, Attributes attributes): вызывается, когда парсер встречает XML-узел.
- endElement(String uri, String localName, String Name): вызывается, когда парсер считал закрывающий тег.
- characters(char[] ch, int start, int length): этот метод вызывается, когда парсер считывает данные из узла.
Напишем класс для парсинга нашего примера public class PersonParser extends DefaultHandler
{
// arraylist для сохранения объектов persons
ArrayList persons;
// вспомогательный объект
Person tempPerson;
// буфер
StringBuilder builder;
/**
* Инициализируем arraylist
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
pesons=new ArrayList();
}
/**
* Инициализируем вспомогательный объект и буфер
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(localName.equalsIgnoreCase.equals("person")){
tempPerson=new Person();
builder=new StringBuilder();
}
}
/**
* Завершение чтения тега person и
* добавление данных в arraylist
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// закончилось чтение person, добавим собранные данные в массив
if(localName.toLowerCase().equals("person"))
{
this.persons.add(tempPerson);
}
// закончилось чтение "firstname", добавим эти данные во вспомогательный объект
else if(localName.toLowerCase().equals("firstname")){
tempPerson.firstName=builder.toString();
}
// закончилось чтение "lastname", добавим эти данные во вспомогательный объект
else if(localName.toLowerCase().equals("lastname")){
tempPerson.lastName=builder.toString();
}
// закончилось чтение "age", добавим эти данные во вспомогательный объект
else if(localName.toLowerCase().equals("age")){
tempPerson.age=Integer.parseInt(builder.toString());
}
}
/**
* Считываем данные из каждого тега
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// читаем символы в буфер
String tempString=new String(ch, start, length);
builder.append(tempString);
}
} Код довольно прост. Парсер проходится по всем узлам, и в зависимости от считанного тега, вы выполняете то или иное действие. Используем этот класс: public ArrayList getPersons(final String response) throws
ParserConfigurationException, SAXException, IOException
{
BufferedReader br=new BufferedReader(new StringReader(response));
InputSource is=new InputSource(br);
PersonParser parser=new PersonParser();
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser sp=factory.newSAXParser();
XMLReader reader=sp.getXMLReader();
reader.setContentHandler(parser);
reader.parse(is);
ArrayList persons=parser.persons;
return persons;
}
Программирование JSON парсера в AndroidНекоторые сервисы могут вернуть ответ не в виде XML, а как JSON массив: "persons" [ { "person"{ "firstName": "John", "lastName": "Smith", "age": 25 } } { "person"{ "firstName": "Catherine", "lastName": "Jones", "age": 35 } } ] Здесь мы видим JSON массив persons, содержащий несколько JSON объектов person. На самом деле, работать с JSON намного проще, чем с XML: public ArrayList<Person> getMessage(String response){
JSONObject jsonResponse;
ArrayList<Person> arrPersons=new ArrayList<Person>;
try {
// получаем ответ
jsonResponse = new JSONObject(response);
// получаем массив
JSONArray persons=jsonResponse.optJSONArray("persons");
// проходимся по массиву и извлекаем персоны
for(int i=0;i<persons.length();i++){
// получаем объект person
JSONObject person=persons.getJSONObject(i);
// получаем firstname
String firstname=person.optString("firstname");
// получаем lastname
String lastname=person.optString("lastname");
// получаем age
int age=person.optInt("age");
// создаем объект и добавляем его в массив
Person p=new Person();
p.firstName=firstname;
p.lastName=lastname;
p.age=age;
arrPersons.add(p);
}
} catch (JSONException e) {
e.printStackTrace();
}
return arrPersons;
} Обратите внимание, здесь мы использовали методы optJSONArray, optString, optInt вместо getString, getInt, поскольку opt-методы эти методы возвращают пустую строку или 0, если какой-то элемент не найден, в то время как get-методы генерируют исключения.
|
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.