Парсинг 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 wink.gif
Хочу заметить, что этот класс не потоко-безопасный wink.gif Поэтому если вы парсите 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

Post a comment