Import org.xml.sax.XMLReader;

Import org.xml.sax.XMLReaderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import java.util.ArrayList;

import chapt16.analyzer.sax.StundentHandler;

importchapt16.entity.Student;

import java.io.IOException;

 

public class SAXStudentMain {

public static void main(String[] args) {

try {

//создание SAX-анализатора

XMLReader reader =

XMLReaderFactory.createXMLReader();

StundentHandler sh = newStundentHandler();

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 */

packagechapt16.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.

/* пример # 8 : запуск JDOM : JDOMStudentMain.java */

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;

}

}