, я включаю поддержку пространства имен XML, регистрирую обработчик
ErrorHandler
и выполняю синтаксический анализ документа. Парсер возвращает документ в виде
DOMDocument
; используя метод
getElementsByTagName
документа
DOMDocument
, я получаю объект
DOMElement
, соответствующий элементу этого документа
animalList
, и просматриваю его дочерние элементы, используя объект типа
DOMNodeList
. Когда я нахожу элемент, имеющий дочерний элемент типа
name
и содержащий текст «
Herby
»,
я удаляю его из документа с помощью вызова метода корневого элемента
removeChild
.
Подобно тому как
SAX2XMLReader
имеет метод
parse
, принимающий экземпляр
InputSource
,
DOMBuilder
имеет метол
parse
, принимающий экземпляр
xercesc::DOMInputSource
(т.е. экземпляр абстрактного класса, который инкапсулирует источник символьных данных). В
DOMInputSource
предусмотрен конкретный подкласс
Wrapper4DOMInputSource
, который может быть использован для преобразования произвольного
InputSource
в
xercesc::DOMInputSource
. См рецепт 14.3.
Наконец, я получаю объект
DOMWriter
из
DOMImplementation
(причем делаю это во многом точно так же, как при получении объекта
DOMBuilder
) и сохраняю модифицированный документ XML на диск, вызывая его метод
writeNode
, передавая в качестве аргумента корневой элемент документа.
Вы должны освободить указатели, возвращаемые методами с именами вида
DOMImplementation::createXXX
, путем вызова метода
release
. Используйте утилиту
DOMPtr
из примера 14.10 для того, чтобы гарантировать освобождение такого указателя, даже если выбрасывается исключение. Необязательно явно удалять указатели, возвращаемые методами, имена которых имеют вид
DOMDocument::createXXX
, хотя это можно делать, если они больше не нужны. Дополнительные сведения вы найдете в документации Xerces.
14.5. Проверка документа XML на соответствие определению DTD
Проблема
Требуется проверить документ XML на соответствие DTD.
Решение
Используйте библиотеку Xerces с парсером SAX2 (простой программный XML-интерфейс) или с парсером DOM.
Для проверки документа XML при использовании SAX2 получите
SAX2XMLReader
, как показано в примере 14.8. Затем включите режим проверки DTD, вызывая метод парсера
setFeature
с аргументами
xercesc::XMLUni::fgSAX2CoreValidation
и
true
. Наконец, зарегистрируйте обработчик
ErrorHandler
для получения уведомлений о нарушении DTD и вызовите метод парсера
parse
, указывая в качестве его аргумента имя вашего документа XML.
Для проверки документа XML при использовании парсера DOM сначала сконструируйте экземпляр
XercesDOMParser
. Затем включите режим проверки DTD, вызывая метод парсера
setValidationScheme
с аргументом
xercesc::XercesDOMParser::Val_Always
. Наконец, зарегистрируйте обработчик
ErrorHandler
для получения уведомлений о нарушении DTD и вызовите метод парсера
parse
, указывая
в качестве его аргумента имя вашего документа XML.
Здесь я использую класс
XercesDOMParser
, т.е. XML-парсер, который входил в состав Xerces еще до того, как был разработан интерфейс
DOMBuilder
— парсера DOM уровня 3. Применение
XercesDOMParser
позволяет немного упростить пример, но при желании вы можете вместо него использовать
DOMBuilder
. См. обсуждение этого рецепта и рецепт 14.4.
Для примера предположим, что вы модифицируете документ XML animals.xml из примера 14.1 для того, чтобы он содержал ссылку на внешнее определение DTD, как показано в примерах 14.11 и 14.12. Программный код, выполняющий проверку документа с использованием программного интерфейса SAX2, приводится в примере 14.13; программный код, выполняющий проверку этого документа с использованием парсера DOM, приводится в примере 14.14.
Пример 14.11. DTD animals.dtd для файла animals.xml
<!-- DTD для животных цирка Feldman Family Circus -->
<!ELEMENT animalList (animal+)>
<!ELEMENT animal (name, species, dateOfBirth,
veterinarian, trainer) >
<!ELEMENT name (#PCDATA)>
<!ELEMENT species (#PCDATA)>
<!ELEMENT dateOfBirth (#PCDATA)>
<!ELEMENT veterinarian EMPTY>
<!ELEMENT trainer EMPTY>
<!ATTLIST veterinarian
name CDATA #REQUIRED
phone CDATA #REQUIRED
>
<!ATTLIST trainer
name CDATA #REQUIRED
phone CDATA #REQUIRED
>
Пример 14.12. Модифицированный файл animals.xml, содержащий DTD
<?xml version="1.0" encodings "UTF-8"?>
<!-- Животные цирка Feldman Family Circus с DTD. – ->
<!DOCTYPE animalList SYSTEM "animals.dtd">
<!- так же, как в примере 14.1 -->
</animalList>
Пример 14.13. Проверка документа animals.xml на соответствие DTD с использованием программного интерфейса SAX2
/*
* Операторы #include из примера 14.8, кроме включения вектора <vector> который
здесь не нужен
*/
#include <stdexcept> // runtime_error
#include <xercesc/sax2/DefaultHandler.hpp>
using namespace std;
using namespace xercesc;
/*
* Определить XercesInitializer, как это сделано в примере 14.8, и
* CircusErrorHandler, как это сделано в примере 14.7