Import org.xml.sax.XMLReaderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import java.util.ArrayList;
import chapt16.analyzer.sax.StundentHandler;
import chapt16.entity.Student;
import java.io.IOException;
public class SAXStudentMain {
public static void main(String[] args) {
try {
//создание SAX-анализатора
XMLReader reader =
XMLReaderFactory.createXMLReader();
StundentHandler sh = new StundentHandler();
reader.setContentHandler(sh);
ArrayList <Student> list;
if (sh!= null) {
//разбор XML-документа
parser.parse("students.xml");
System. out. println(sh.getStudents());
}
} catch (SAXException e) {
e.printStackTrace();
System. out. print("ошибка SAX парсера");
} catch (ParserConfigurationException e) {
e.printStackTrace();
System. out. print("ошибка конфигурации");
} catch (IOException e) {
e.printStackTrace();
System. out. print("ошибка I/О потока");
}
}
}
В результате на консоль будет выведена следующая информация:
Parsing started
Login: mit
Name: Mitar Alex
Telephone: 2456474
Faculty: mmf
Address:
Country: Belarus
City: Minsk
Street: Kalinovsky 45
Login: pus
Name: Pashkun Alex
Telephone: 3453789
Faculty: mmf
Address:
Country: Belarus
City: Brest
Street: Knorina 56
Класс, объект которого формируется на основе информации из XML-документа, имеет следующий вид:
/* пример # 5: класс java bean: Student.java */package chapt16.entity;
public class Student {
private String login;
private String name;
private String faculty;
private String telephone;
private Address address = new Address();
public String getLogin() {
return login;
}
public void setLogin(String login) {
this. login = login;
}
public String getName() {
return name;
}
public void setName(String name) {
this. name = name;
}
public String getFaculty() {
return faculty;
}
public void setFaculty(String faculty) {
this. faculty = faculty;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this. telephone = telephone;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this. address = address;
}
public String toString() {
return "Login: " + login
+ "\nName: " + name
+ "\nTelephone: " + telephone
+ "\nFaculty: " + faculty
+ "\nAddress:"
+ "\n\tCountry: " + address.getCountry()
+ "\n\tCity: " + address.getCity()
+ "\n\tStreet: " + address.getStreet()
+ "\n";
}
public class Address { //внутренний класс
private String country;
private String city;
private String street;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this. country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this. city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this. street = street;
}
}
}
Древовидная модель
Анализатор DOM представляет собой некоторый общий интерфейс для работы со структурой документа. При разработке DOM-анализаторов различными вендорами предполагалась возможность ковариантности кода.
DOM строит дерево, которое представляет содержимое XML-документа, и определяет набор классов, которые представляют каждый элемент в XML-документе (элементы, атрибуты, сущности, текст и т.д.).
В пакете org.w3c.dom можно найти интерфейсы, которые представляют вышеуказанные объекты. Реализацией этих интерфейсов занимаются разработчики анализаторов. Разработчики приложений, которые хотят использовать DOM-анализатор, имеют готовый набор методов для манипуляции деревом объектов и не зависят от конкретной реализации используемого анализатора.
Существуют различные общепризнанные DOM-анализаторы, которые в настоящий момент можно загрузить с указанных адресов:
Xerces – http://xerces.apache.org/xerces2-j/;
JAXP – входит в JDK.
Существуют также библиотеки, предлагающие свои структуры объектов XML с API для доступа к ним. Наиболее известные:
JDOM–http://www.jdom.org/dist/binary/jdom-1.0.zip.
dom4j – http://www.dom4j.org
Xerces
В стандартную конфигурацию Java входит набор пакетов для работы с XML. Но стандартная библиотека не всегда является самой простой в применении, поэтому часто в основе многих проектов, использующих XML, лежат библиотеки сторонних производителей. Одной из таких библиотек является Xerces, замечательной особенностью которого является использование части стандартных возможностей XML-библиотек JSDK с добавлением собственных классов и методов, упрощающих и облегчающих обработку документов XML.
Org.w3c.dom.Document
Используется для получения информации о документе и изменения его структуры. Это интерфейс представляет собой корневой элемент XML-документа и содержит методы доступа ко всему содержимому документа.
Element getDocumentElement() — возвращает корневой элемент документа.
Org.w3c.dom.Node
Основным объектом DOM является Node – некоторый общий элемент дерева. Большинство DOM-объектов унаследовано именно от Node. Для представления элементов, атрибутов, сущностей разработаны свои специализации Node.
Интерфейс Node определяет ряд методов, которые используются для работы с деревом:
short getNodeType() – возвращает тип объекта (элемент, атрибут, текст, CDATA и т.д.);
String getNodeValue() – возвращает значение Node;
Node getParentNode() – возвращает объект, являющийся родителем текущего узла Node;
NodeList getChildNodes() – возвращает список объектов, являющихся дочерними элементами;
Node getFirstChild(), Node getLastChild() – возвращает первый и последний дочерние элементы;
NamedNodeMap getAttributes() – возвращает список атрибутов данного элемента.
У интерфейса Node есть несколько важных наследников – Element, Attr, Text. Они используются для работы с конкретными объектами дерева.
Org.w3c.dom.Element
Интерфейс предназначен для работы с содержимым элементов XML-документа. Некоторые методы:
String getTagName(String name) – возвращает имя элемента;
boolean hasAttribute() – проверяет наличие атрибутов;
String getAttribute(String name) – возвращает значение атрибута по его имени;
Attr getAttributeNode(String name) – возвращает атрибут по его имени;
void setAttribute(String name, String value) – устанавливает значение атрибута, если необходимо, атрибут создается;
void removeAttribute(String name) – удаляет атрибут;
NodeList getElementsByTagName(String name) – возвращает список дочерних элементов с определенным именем.
Org.w3c.dom.Attr
Интерфейс служит для работы с атрибутами элемента XML-документа.
Некоторые методы интерфейса Attr:
String getName() – возвращает имя атрибута;
Element getOwnerElement – возвращает элемент, который содержит этот атрибут;
String getValue() – возвращает значение атрибута;
void setValue(String value) – устанавливает значение атрибута;
boolean isId() – проверяет атрибут на тип ID.
Org.w3c.dom.Text
Интерфейс Text необходим для работы с текстом, содержащимся в элементе.
String getWholeText() – возвращает текст, содержащийся в элементе;
void replaceWholeText(String content) – заменяет строкой
content весь текст элемента.
В следующих примерах производятся разбор документа students.xml
с использованием DOM-анализатора и инциализация на его основе набора объектов.
/* пример # 6: создание анализатора и загрузка XML-документа:
DOMLogic.java*/
package chapt16.main;
import java.util.ArrayList;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
//import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import chapt16.analyzer.dom.Analyzer;
import chapt16.entity.Student;
public class DOMLogic {
public static void main(String[] args) {
try {
// создание DOM-анализатора(JSDK)
DocumentBuilderFactory dbf=
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// распознавание XML-документа
Document document = db.parse("students.xml");
// создание DOM-анализатора (Xerces)
/* DOMParser parser = new DOMParser();
parser.parse("students.xml");
Document document = parser.getDocument();*/
Element root = document.getDocumentElement();
ArrayList<Student> students = Analyzer.listBuilder(root);
for (int i = 0; i < students.size(); i++) {
System.out.println(students.get(i));
}
} catch (SAXException e) {
e.printStackTrace();
System. out. print("ошибка SAX парсера");
} catch (ParserConfigurationException e) {
e.printStackTrace();
System. out. print("ошибка конфигурации");
} catch (IOException e) {
e.printStackTrace();
System. out. print("ошибка I/О потока");
}
}
}
/* пример # 7: создание объектов на основе объекта типа Element:
Analyzer.java */
package chapt16.analyzer.dom;
import java.util.ArrayList;
import java.io.IOException;
import org.xml.sax.SAXException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import chapt16.entity.Student;
public class Analyzer {
public static ArrayList<Student> listBuilder(Element root)
throws SAXException, IOException {
ArrayList<Student> students
= new ArrayList<Student>();
// получение списка дочерних элементов <student>
NodeList studentsNodes =
root.getElementsByTagName("student");
Student student = null;
for (int i = 0; i < studentsNodes.getLength(); i++) {
student = new Student();
Element studentElement =
(Element) studentsNodes.item(i);
// заполнение объекта student
student.setFaculty(studentElement.getAttribute("faculty"));
student.setName(getBabyValue(studentElement, "name"));
student.setLogin(studentElement.getAttribute("login"));
student.setTelephone(
getBabyValue(studentElement, "telephone"));
Student.Address address = student.getAddress();
// заполнение объекта address
Element addressElement =
getBaby(studentElement, "address");
address.setCountry(
getBabyValue(addressElement, "country"));
address.setCity(
getBabyValue(addressElement, "city"));
address.setStreet(
getBabyValue(addressElement, "street"));
students.add(student);
}
return students;
}
// возвращает дочерний элемент по его имени и родительскому элементу
private static Element getBaby(Element parent,
String childName) {
NodeList nlist =
parent.getElementsByTagName(childName);
Element child = (Element) nlist.item(0);
return child;
}
// возвращает текст, содержащийся в элементе
private static String getBabyValue(Element parent,
String childName) {
Element child = getBaby(parent, childName);
Node node = child.getFirstChild();
String value = node.getNodeValue();
return value;
}
}
JDOM
JDOM не является анализатором, он был разработан для более удобного, более интуитивного для Java-программист, доступа к объектной модели XML-документа. JDOM представляет свою модель, отличную от DOM. Для разбора документа JDOM использует либо SAX-, либо DOM-парсеры сторонних производителей. Реализаций JDOM немного, так как он основан на классах, а не на интерфейсах.
Разбирать XML-документы с помощью JDOM проще, чем с помощью Xerces. Иерархия наследования объектов документа похожа на Xerces.
Content
В корне иерархии наследования стоит класс Content, от которого унаследованы остальные классы (Text, Element и др.).
Основные методы класса Content:
Document getDocument() – возвращает объект, в котором содержится этот элемент;
Element getParentElement() – возвращает родительский элемент.
Document
Базовый объект, в который загружается после разбора XML-документ. Аналогичен Document из Xerces.
Element getRootElement() – возвращает корневой элемент.
Parent
Интерфейс Parent реализуют классы Document и Element. Он содержит методы для работы с дочерними элементами. Интерфейс Parent и класс
Content реализуют ту же функциональность, что и интерфейс Node в Xerces.
Некоторые из его методов:
List getContent() – возвращает все дочерние объекты;
Content getContent(int index) – возвращает дочерний элемент по его индексу;
int getContentSize() – возвращает количество дочерних элементов;
Parent getParent() – возвращает родителя этого родителя;
int indexOf(Content child) – возвращает индекс дочернего элемента.
Element
Класс Element представляет собой элемент XML-документа.
Attribute getAttribute(String name) – возвращает атрибут по его имени;
String getAttributeValue(String name) – возвращает значение атрибута по его имени;
List getAttributes() – возвращает список всех атрибутов;
Element getChild(String name) – возвращает дочерний элемент по имени;
List getChildren() – возвращает список всех дочерних элементов;
String getChildText(String name) – возвращает текст дочернего элемента;
String getName() – возвращает имя элемента;
String getText() – возвращает текст, содержащийся в элементе.
Text
Класс Text содержит методы для работы с текстом. Аналог в Xerces –интерфейс Text.
String getText() – возвращает значение содержимого в виде строки;
String getTextTrim() – возвращает значение содержимого без крайних пробельных символов.
Attribute
Класс Attribute представляет собой атрибут элемента XML-документа.
В отличие от интерфейса Attr из Xerces, у класса Attribute расширенная функциональность. Класс Attribute имеет методы для возвращения значения определенного типа.
int getAttributeType() – возвращает тип атрибута;
тип get Тип Type() –(Int, Double, Boolean, Float, Long) возвращает значение определенного типа;
String getName() – возвращает имя атрибута;
Element getParent() – возвращает родительский элемент.
Следующие примеры выполняют ту же функцию, что и предыдущие, только
с помощью JDOM.
package chapt16.main;
import java.util.List;
import org.jdom.*;
import org.jdom.input.SAXBuilder;
import java.io.IOException;
import chapt16.analyzer.dom.JDOMAnalyzer;
import chapt16.entity.Student;
public class JDOMStudentMain {
public static void main(String[] args) {
try {
//создание JDOM
SAXBuilder builder = new SAXBuilder();
//распознавание XML-документа
Document document = builder.build("students.xml");
List<Student> list =
JDOMAnalyzer. listCreator (document);
for (Student st: list) System. out. println(st);
} catch (IOException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
}
}
}
/* пример # 9: создание объектов с использованием JDOM: JDOMAnalyzer.java */ package chapt16.analyzer.dom;import java.util.*;
import java.io.IOException;
import org.jdom.Element;
import org.jdom.Document;
import org.jdom.JDOMException;
import chapt16.entity.Student;
public class JDOMAnalyzer {
public static List<Student> listCreator(Document doc)
throws JDOMException, IOException {
//извлечение корневого элемента
Element root = doc.getRootElement();
//получение списка дочерних элементов <student>
List studElem = root.getChildren();
Iterator studentIterator = studElem.iterator();
//создание пустого списка объектов типа Student
ArrayList<Student> students =
new ArrayList<Student>();
while (studentIterator.hasNext()) {
Element studentElement =
(Element)studentIterator.next();
Student student = new Student();
//заполнение объекта student
student.setLogin(
studentElement.getAttributeValue("login"));
student.setName(
studentElement.getChild("name").getText());
student.setTelephone(
studentElement.getChild("telephone").getText());
student.setFaculty(
studentElement.getAttributeValue("faculty"));
Element addressElement =
studentElement.getChild("address");
Student.Address address = student.getAddress();
//заполнение объекта address
address.setCountry(addressElement.getChild("country")
.getText());
address.setCity(addressElement.getChild("city").getText());
address.setStreet(addressElement.getChild("street")
.getText());
students.add(student);
}
return students;
}
}