Парсинг XML в Google Android
Введение
Более подробно можете почитать о Document Object Model(DOM) в википедии. Лучше в английской.
В крадце опишу.
Есть некий документ, который представим в виде дерева. Пусть будет HTML-код:
<paragraph align="left"> The <it>Italicized</it> portion. </paragraph>
В результате он будет преобразован к вот такому дереву:

Как видно(это верно и для Android Java) текст внутри тега помещается в отдельный узел(лист) дерева.
Это нужно не забывать, когда будем работать с этим деревом!
Начало. Загрузка XML-файла.
Приведу код, надеюсь он не будет требовать пояснений:
//Собственно наш документ
Document doc = null;
try {
//Создаем фабрику для создания постоителя документов.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//Непосредственно постоитель
DocumentBuilder db = dbf.newDocumentBuilder();
//И наш документ. Тут мы передаем поток с XML-файлом,
//находящимся на карте памяти
doc = db.parse(new FileInputStream("/sdcard/Test.xml"));
} catch (Exception ioe) {
//Обрабатываем ошибку
}
Работа напрямую с объектом класса Document.
И так. Мы получили наш экземпляр класса Document.
Доступ к определенному элементу происходит так:
//Получение списка ВСЕХ узлов дерева с тегом myTag.
//Результат не зависит от того, где находятся эти узлы.
NodeList list = doc.getElementsByTagName("myTag");
int count = list.length();
for(int i = 0; i<count; i++)
{
Node n= list.item(i);
//Собственно здесь и обрабатываем все элементы.
n.getNodeValue();//Получение значения элемента. Внизу опишу пояснения небольшие.
n.getFirstChild();//Получение первого ребенка.
//и т.д.
}
Warring!
Покажу как нужно правильно работать с деревом в связи с пунктом “Введение”.
К примеру, есть xml-ка:
<myTag>
androidforums.ru %)
</myTag>
И если мы вызовем n.getNodeValue(), то мы не получим строку "androidforums.ru %)", поскольку в иерархии создается для этого текста отдельный ребенок(как уже было сказано выше), т.е. правильно стоит писать так:
n.getFirstChilt().getNodeValue();
И результатом будет строка “\n androidforums.ru %)\n”
Работа с использованием XPath
Еще нету в SDK Андроида……… но сейчас написал небольшой класс для получению узлов из пути.
Он на вход получает либо документ, либо узер дерева, а так же путь к элементу вида “node1/node2/node3″.
Document отлично кастится в Node ![]()
Хочу заметить, что этот класс не потоко-безопасный
Поэтому если вы парсите XML в несколько потоков, то создавайте свой экземпляр класса.
Пример использования:
SimpleXPath xpath = new SimpleXPath(); Node[] result= xpath.GetXPathNodes(doc, "outertag/innertag/mytag");
Вот и сам класс:
package hotheart.XmlTest;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class SimpleXPath {
public static final String XPATH_SEPARATOR = "/";
List<node> result = null;
public Node[] GetXPathNodes(Node root, String path) {
result = new ArrayList<node>();
XPathGetNodes(root, path);
Node[] res = new Node[result.size()];
res = result.toArray(res);
result = null;
return res;
}
void XPathGetNodes(Node root, String path) {
String[] node = path.split(XPATH_SEPARATOR, 2);
boolean isFinishing = node.length == 1;
Node n = root.getFirstChild();
while (n != null) {
if (node[0].equals(n.getNodeName())) {
if (isFinishing)
result.add(n);
else
XPathGetNodes(n, node[1]);
}
try {
n = n.getNextSibling();
} catch (Exception e) {
n = null;
}
}
}
}
Трекбек
Ссылка для трекбека:
http://stepa.name/archives/17/trackback
Комментарии
……
Подписался на RSS …
Автор: Vasya | 02.04.2010 09:06