ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Определение сущностиСущность (entity) представляет собой некоторое определение, чье содержимое может быть повторно использовано в документе. Описывается сущность с помощью дескриптора !ENTITY: <!ENTITY company 'Sun Microsystems'><sender>&company;</sender>Программа-анализатор, которая будет обрабатывать файл, автоматически подставит значение Sun Microsystems вместо &company. Для повторного использования содержимого внутри описания DTD используются параметрические (параметризованные) сущности. <!ENTITY % elementGroup “firstName, lastName,gender, address, phone”> <!ELEMENT employee (%elementGroup;)> <!ELEMENT contact (%elementGroup)> В XML включены внутренние определения для символов. Кроме этого, есть внешние определения, которые позволяют включать содержимое внешнего файла: <!ENTITY logotype SYSTEM "/image.gif" NDATA GIF87A>Файл DTD для документа students.xml будет иметь вид: <?xml version='1.0' encoding='UTF-8'?> <!ELEMENT students (student)+> <!ELEMENT student (name, telephone, address)> <!ATTLIST student login ID #REQUIRED faculty CDATA #REQUIRED > <!ELEMENT name (#PCDATA)> <!ELEMENT telephone (#PCDATA)> <!ELEMENT address (country, city, street)> <!ELEMENT country (#PCDATA)> <!ELEMENT city (#PCDATA)> <!ELEMENT street (#PCDATA)> Схема XSD Схема XSD представляет собой более строгое, чем DTD, описание XML-документа. XSD-схема, в отличие от DTD, сама является XML-документом и поэтому более гибкая для использования в приложениях, задания правил документа, дальнейшего расширения новой функциональностью. В отличиеи от DTD, эта схема содержит много базовых типов (44 типа) и имеет поддержку пространств имен (namespace). С помощью схемы XSD можно также проверить документ на корректность. Схема XSD первой строкой должна содержать декларацию XML <?xml version="1.0" encoding="UTF-8"?>Любая схема своим корневым элементом должна содержать элемент schema. Для создания схемы нужно описать все элементы: их тип, количество повторений, дочерние элементы. Сам элемент создается элементом element, который может включать следующие атрибуты: ref – ссылается на определение элемента, находящегося в другом месте; name – определяет имя элемента; type – указывает тип элемента; minOccurs и maxOccurs – количество повторений этого элемента (по умолчанию 1), чтобы указать, что количество элементов неограниченно, в атрибуте maxOccurs нужно задать unbounded. Если стандартные типы не подходят, можно создать свой собственный тип элемента. Типы элементов делятся на простые и сложные. Различия заключаются в том, что сложные типы могут содержать другие элементы, а простые – нет. Простые типы Элементы, которые не имеют атрибутов и дочерних элементов, называются простыми и должны иметь простой тип данных. Существуют стандартные простые типы, например string (представляет строковое значение), boolean (логическое значение), integer (целое значение), float (значение с плавающей точкой), ID (идентификатор) и др. Также простые типы можно создавать на основе существующих типов посредством элемента simpleType. Атрибут name содержит имя типа. Все типы в схеме могут быть объявлены как локально внутри элемента, так и глобально с использованием атрибута name для ccылки на тип в любом месте схемы. Для указания основного типа используется элемент restriction. Его атрибут base указывает основной тип. В элемент restriction можно включить ряд ограничений на значения типа: minInclusive – определяет минимальное число, которое может быть значением этого типа; maxInclusive – максимальное значение типа; length – длина значения; pattern – определяет шаблон значения; enumeration – служит для создания перечисления. Следующий пример описывает тип Login, производный от ID и отвечающий заданному шаблону в элементе pattern. <simpleType name="Login"> <restriction base="ID"> <pattern value="[a-zA-Z]{3}[a-zA-Z0-9_]+"/> </restriction> </simpleType> Сложные типы Элементы, содержащие в себе атрибуты и/или дочерние элементы, называются сложными. Сложные элементы создаются с помощью элемента complexType. Так же как и в простом типе, атрибут name задает имя типа. Для указания, что элементы должны располагаться в определенной последовательности, используется элемент sequence. Он может содержать элементы element, определяющие содержание сложного типа. Если тип может содержать не только элементы, но и текстовую информацию, необходимо задать значение атрибута mixed в true. Кроме элементов, тип может содержать атрибуты, которые создаются элементом Следующий пример демонстрирует описание типа Student: <complexType name="Student"> <sequence> <element name="name" type="string"/> <element name="telephone" type="decimal"/> <element name="address" type="tns:Address"/> </sequence> <attribute name="login" type="tns:Login" use="required"/> <attribute name="faculty" type="string" use="required"/> </complexType> Для объявления атрибутов в элементах, которые могут содержать только текст, используются элемент simpleContent и элемент extension, с помощью которого расширяется базовый тип элемента атрибутом(ами). <element name="Student"> <complexType> <simpleContent> <extension base="string"> <attribute name="birthday" type="string"/> </extension> </simpleContent> </complexType> </element> Для расширения/ограничения ранее объявленных сложных типов используется элемент complexContent. <complexType name=”personType”> <sequence> <element name=”firstName” type=”string”/> <element name=”lastName” type=”string”/> <element name=”address” type=”string”/> </sequence> </complexType> <complexType name=”studentType”> <complexContent> <extension base=”personType”> <sequence> <element name=”course” type=”integer”/> <element name=”faculty” type=”string”/> </sequence> </extesion> </complexContent> </complexType> <element name=”Student” type=”studentType”/> Для задания порядка следования элементов в XML используются такие теги, как <all>, который допускает любой порядок. <element name=”person”> <complexType> <all> <element name=”firstName” type=”string”/> <element name=”lastName” type=”string”/> </all> </complexType> </element> Элемент <choice> указывает, что в XML может присутствовать только один из перечисленных элементов. Элемент <sequence> задает строгий порядок дочерних элементов. Для списка студентов XML-схема students.xsd может выглядеть следующим образом: <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/Students" xmlns:tns="http://www.example.com/Students"> <element name="students"> <complexType> <sequence> <element name="student" type="tns:Student" minOccurs="1" maxOccurs="unbounded" /> </sequence> </complexType> </element> <complexType name="Student"> <sequence> <element name="name" type="string" /> <element name="telephone" type="decimal" /> <element name="address" type="tns:Address" /> </sequence> <attribute name="login" type="tns:Login" use="required" /> <attribute name="faculty" type="string" use="required" /> </complexType> <simpleType name="Login"> <restriction base="ID"> <pattern value="[a-zA-Z]{3}[a-zA-Z0-9_]*"/> </restriction> </simpleType> <complexType name="Address"> <sequence> <element name="country" type="string" /> <element name="city" type="string" /> <element name="street" type="string" /> </sequence> </complexType> </schema> В приведенном примере используется понятие пространства имен namespace. Пространство имен введено для разделения наборов элементов с соответствующими правилами, описанными схемой. Пространство имен объявляется с помощью атрибута xmlns и префикса, который используется для элементов из данного пространства. Например, xmlns="http://www.w3.org/2001/XMLSchema" задает пространство имен по умолчанию для элементов, атрибутов и типов схемы, которые принадлежат пространству имен "http://www.w3.org/2001/XMLSchema" и описаны соответствующей схемой. Атрибут targetNamespace="http://www.example.com/Students" задает пространство имен для элементов/атрибутов, которые описывает данная схема. Атрибут xmlns:tns="http://www.example.com/Students" вводит префикс для пространства имен (элементов) данной схемы. То есть для всех элементов, типов, описанных данной схемой и используемых здесь же требуется использовать префикс tns, как в случае с типами – tns:Address, tns:Login и т.д. Действие пространства имён распространяется на элемент, где он объявлен, и на все дочерние элементы. Тогда для проверки документа объекту-парсеру следует дать указание использовать DTD или схему XSD, и в XML-документ вместо ссылки на DTD добавить вместо корневого элемента <students> элемент <tns:students> вида: <tns:students xmlns:tns="http://www.example.com/Students" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/Students students.xsd "> Следующий пример выполняет проверку документа на корректность средствами языка Java. /* пример # 13: проверка корректности документа XML: XSDMain.java */ package chapt16.xsd; import java.io.IOException; import org.xml.sax.SAXException; import org.apache.xerces.parsers.DOMParser; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import chapt16.xsd.MyErrorHandler;
public class XSDMain { public static void main(String[] args) {
String filename = "students.xml"; DOMParser parser = new DOMParser(); try { // установка обработчика ошибок parser.setErrorHandler(new MyErrorHandler("log.txt"));
// установка способов проверки с использованием XSD parser.setFeature( "http://xml.org/sax/features/validation", true); parser.setFeature( "http://apache.org/xml/features/validation/schema", true);
parser.parse(filename); } catch (SAXNotRecognizedException e) { e.printStackTrace(); System. out. print("идентификатор не распознан"); } catch (SAXNotSupportedException e) { e.printStackTrace(); System. out. print("неподдерживаемая операция");
} catch (SAXException e) { e.printStackTrace(); System. out. print("глобальная SAX ошибка "); } catch (IOException e) { e.printStackTrace(); System. out. print("ошибка I/O потока");
} System. out. print("проверка " + filename + " завершена"); } } Класс обработчика ошибок может выглядеть следующим образом: /* пример # 14: обработчик ошибок: MyErrorHandler.java */package chapt16.xsd; import java.io.IOException; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXParseException; import org.apache.log4j.FileAppender; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout;
public class MyErrorHandler implements ErrorHandler { private Logger logger;
public MyErrorHandler(String log) throws IOException { //создание регистратора ошибок chapt16.xsd logger = Logger.getLogger("chapt16.xsd"); //установка файла и формата вывода ошибок logger.addAppender(new FileAppender( new SimpleLayout(), log)); } public void warning(SAXParseException e) { logger.warn(getLineAddress(e) + "-" + e.getMessage()); } public void error(SAXParseException e) { logger.error(getLineAddress(e) + " - " + e.getMessage()); } public void fatalError(SAXParseException e) { logger.fatal(getLineAddress(e) + " - " + e.getMessage()); } private String getLineAddress(SAXParseException e) { //определение строки и столбца ошибки return e.getLineNumber() + ": " + e.getColumnNumber(); } } Чтобы убедиться в работоспособности кода, следует внести в исходный XML-документ ошибку. Например, сделать идентичными значения атрибута login. Тогда в результате запуска в файл будут выведены следующие сообщения обработчика об ошибках: ERROR - 14: 41 - cvc-id.2: There are multiple occurrences of ID value 'mit'. ERROR - 14: 41 - cvc-attribute.3: The value 'mit' of attribute 'login' on element 'student' is not valid with respect to its type, 'login'. Если допустить синтаксическую ошибку в XML-документе, например, удалить закрывающую скобку в элементе telephone, будет выведено сообщение о фатальной ошибке: FATAL - 7: 26 - Element type "telephone2456474" must be followed by either attribute specifications, ">" or "/>". В Java разработаны серьезные способы взаимодействия с XML. Начиная Следующий пример на основе внутреннего класса создает структуру документа XML и сохраняет в ней объект. /* пример # 15: создание XML-документа на основе объекта: DemoJSR.java */package chapt16; import java.io.*; import javax.xml.bind.*; import javax.xml.bind.annotation.*;
public class DemoJSR { public static void main(String[] args) { try { JAXBContext context = JAXBContext. newInstance (Student. class); Marshaller m = context.createMarshaller(); Student s = new Student(1, "Bender"); //объект m.marshal(s, new FileOutputStream("stud.xml")); } catch (FileNotFoundException e) { System. out. println("XMl-файл не найден"); e.printStackTrace(); } catch (JAXBException e) { System. out. println("JAXB-исключения"); e.printStackTrace(); } } @XmlRootElement private static class Student { //внутренний класс private int id; private String name;
public Student() { } public Student(int id, String name) { this. id = id; this. name = name; } public int getID() { return id; } public String getName() { return name; } public void setID(int id) { this. id = id; } public void setName(String name) { this. name = name; } } } В результате компиляции и запуска программы будет создан XML-документ: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <ID>1</ID> <name>Bender</name> </student> Возможно обратное создание на основе XML-схемы классов на языке Java: /* пример # 16: описание классов University, Course и перечисления Faculty в XSD-схеме: student.xsd*/<schema xmlns="http://www.w3c.org/2001/XMLSchema" xmlns:Revealed="http://www.university.net" targetNamespace="http://www.university.net"> <element name="University"> <complexType> <sequence> <element name="faculty" type="Revealed:Faculty"/> <element name="course" type="Revealed:Course"/> </sequence> </complexType> </element> <complexType name="Course"> <sequence> <element name="login" type="string"/> <element name="name" type="string"/> <element name="telephone" type="string"/> </sequence> </complexType> <simpleType name="Faculty"> <restriction base="string"> <enumeration value="FPMI"></enumeration> <enumeration value="MMF"></enumeration> <enumeration value="Geo"></enumeration> </restriction> </simpleType> </schema> Запуск выполняется с помощью командной строки: Xjc student.xsd В результате будет сгенерирован следующий код классов: package net.university; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; @XmlEnum public enum Faculty { FPMI ("FPMI"), MMF ("MMF"), @XmlEnumValue("Geo") GEO_F ("Geo"); private final String value;
Faculty(String v) { value = v; } public String value() { return value; } public static Faculty fromValue(String v) { for (Faculty c: Faculty. values ()) { if (c.value.equals(v)) { return c; } } throw new IllegalArgumentException(v.toString()); } } package net.university; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for Course complex type. */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "Course", propOrder = { "login", "name", "telephone" }) public class Course {
@XmlElement(required = true) protected String login; @XmlElement(required = true) protected String name; @XmlElement(required = true) protected String telephone; public String getLogin() { return login; } public void setLogin(String value) { this. login = value; } public String getName() { return name; } public void setName(String value) { this. name = value; } public String getTelephone() { return telephone; } public void setTelephone(String value) { this. telephone = value; } } package net.university; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for anonymous complex type. */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "faculty", "course" }) @XmlRootElement(name = "University") public class University {
@XmlElement(required = true) protected Faculty faculty; @XmlElement(required = true) protected Course course; public Faculty getFaculty() { return faculty; } public void setFaculty(Faculty value) { this. faculty = value; } public Course getCourse() { return course; } public void setCourse(Course value) { this. course = value; } } package net.university; import javax.xml.bind.annotation.XmlRegistry; @XmlRegistry public class ObjectFactory { public ObjectFactory() { } public Course createCourse() { return new Course(); } public University createUniversity() { return new University(); } } XML-анализаторы XML как набор байт в памяти, запись в базе или текстовый файл представляет собой данные, которые еще предстоит обработать. То есть из набора строк необходимо получить данные, пригодные для использования в программе. Поскольку ХML представляет собой универсальный формат для передачи данных, существуют универсальные средства его обработки – XML-анализаторы (парсеры). Парсер – это библиотека (в языке Java: класс), которая читает XML-документ, а затем предоставляет набор методов для обработки информации этого документа. Не нашли, что искали? Воспользуйтесь поиском:
|