Пусть у нас имеется xml файл в котором хранится список студентов.
<students>
<student>
<name>Nikolaj</name>
<surname>Ivanov</surname>
<age>23</age>
<group>PF-11</group>
</student>
<student>
<name>Petr</name>
<surname>Kilkin</surname>
<age>22</age>
<group>FP-22</group>
</student>
</students>
перед нами стоит задача извлечь данные о студентах в список (например ArrayList) для дальнейшей обработки.
Первое что сделаем - напишем класс, который будет описывать студента:
class Student{
private String name="";
private String surname="";
private int age="";
private String group="";
// самостоятельно добавьте конструктор, а также
// getXXX() и setXXX() методы для каждого параметра
}
Теперь переходим к написанию парсера. Основной идеей Dom парсера есть перебор по дереву всех элементов хмл файла. Наш класс - парсер будет читать хмл файл и выбирать все необходимые данные оттуда. Сразу приведу пример такого класса:
//Dom Parser
import java.util.*;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
public class DomStudParser
{
private Document doc = null;
private String txt = "";
private Student tmpS = null;
private List stds = null;
// fName - имя хмл файла
public DomHostsParser(String fName)
{
try
{
doc = parserXML(new File(fName));
stds = new ArrayList();
visit(doc, 0);
Host tmp=null;
}
catch(Exception error)
{
error.printStackTrace();
}
}
public void visit(Node node, int level)
{
NodeList nl = node.getChildNodes();
String parent="";
for(int i=0, cnt=nl.getLength(); i<cnt; i++)
{
if (nl.item(i).getNodeType()==Node.TEXT_NODE){ // if1
parent=nl.item(i).getParentNode().getNodeName();
txt=nl.item(i).getNodeValue();
if (parent=="name"){ // if1.1
tmpS.setName(txt);
}
if (parent=="surname"){ // if1.2
tmpS.setSurname(txt);
}
if (parent=="age"){ // if1.3
tmpS.setAge(Integer.valueOf(txt));
}
if (parent=="group"){
tmpS.setGroup(txt);
}
} else {
if (nl.item(i).getNodeName().equals("student")){
tmpS=new Student();
stds.add(tmpS);
}
}
System.out.println(nl.item(i).getNodeName() + " = " + nl.item(i).getNodeValue());
visit(nl.item(i), level+1);
}
}
public Document parserXML(File file) throws SAXException, IOException, ParserConfigurationException
{
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
}
public List getStds() {
return stds;
}
public void setStds(List stds) {
this.stds = stds;
}
}
Итак немного объяснений.
Функция parserXML преобразовывает наш хмл файл в хмл документ, над которым может проводить работу.
Основной в данном классе - рекурсивно вызываемый метод visit, который по дереву (поиск в глубину) перебирает все узлы нашего хмл елемента.
Узлы бывают нескольких типов: название атрибута, название элемента, значение элемента, коментарий и т.д.
В нашем случае узлы только 2х типов - это TEXT_NODE (значение элемента) и ELEMENT_NODE (название элемента). Парсер начинает просмотр с элемента "<students>" , далее обработке подвергнется "текст", который находится между тегами <students> и <student> , далее элемент <student> , при достижении которого сработает условие "else if" и будет создан новый экземпляр класса Student, который мы начнём заполнять. Когда дойдём до текста после элемента <name> - "Nikolaj" , сработает условие if1.1.Это произойдт потому что родителем для данного текста есть элемент name и т.д. мы переберём все элементы и в итоге получим List с двумя объектами Student внутри, получить этот список можна с помощью функции getStds().
подробнее:
http://java.sun.com/j2se/1.4.2/docs/api/org/w3c/dom/package-summary.html
4 комментария:
private int age="";
как то не логично числу строку присваивать!
спасибо. код писал на автомате не компилируя.
как итерироваться то по NodeListу? чтоб без вот этих индексов
Отправить комментарий