if (impl == 0) {
cout << 'couldn't create DOM implementation
';
return EXIT_FAILURE;
}
// Сконструировать DOMBuilder для анализа документа animals.xml.
DOMPtr<DOMBuilder> parser =
static_cast<DOMImplementationLS*>(impl)->
createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
// Подключить пространства имен (они не требуются в этом примере)
parser->setFeature(XMLUni::fgDOMNamespaces, true);
// Зарегистрировать обработчик ошибок
CircusErrorHandler err;
parser->setErrorHandler(&err);
// Выполнить синтаксический анализ animals.xml; здесь можно
// использовать URL вместо имени файла
DOMDocument* doc =
parser->parseURI('animals.xml');
// Найти элемент слона Herby: сначала получить указатель на элемент
// 'animalList'.
DOMElement* animalList = doc->getDocumentElement();
if (animalList->getTagName() != fromNative('animalList')) {
cout << 'bad document root: '
<< toNative(animalist->getTagName()) << '
';
return EXIT_FAILURE;
}
// Затем просматривать элементы 'animal', пытаясь найти элемент слона
// Herby.
DOMNodeList* animals =
animaIList->getElementsByTagName(fromNative('animal').c_str());
for (size_t i = 0,
len = animals->getLength(); i < len; ++i) {
DOMElement* animal =
static_cast<DOMElement'>(animals->item(i));
const XMLCh* name = getAnimalName(animal);
if (name != 0 && name == fromNative('Herby')) {
// Herby найден - удалить его из документа.
animalList->removeChild(animal);
animal->release();
// необязательный оператор.
break;
}
}
// Сконструировать DOMWriter для сохранения animals.xml.
DOMPtr<DOMWriter> writer =
static cast<DOMImplementationLS*>(impl)->createDOMWriter();
writer->setErrorHandler(&err);
// Сохранить animals.xml.
LocalFileFormatTarget file('animals.xml');
writer->writeNode(&file, *animalList);
} catch (const SAXException& e) {
cout << 'xml error: ' << toNative(e.getMessage()) << '
';
return EXIT_FAILURE;
} catch (const DOMException& e) {
cout << 'xml error: ' << toNative(e.getMessage()) << '
';
return EXIT_FAILURE;
} catch (const exception& e) {
cout << e.what() << '
';
return EXIT_FAILURE;
}
}
Подобно парсеру TinyXml парсер Xerces DOM на выходе формирует документ XML в виде объекта C++, имеющего структуру дерева, узлы которого представляют компоненты документа. Однако парсер Xerces существенно сложнее: например, в отличие от TinyXml он «понимает» пространства имен XML и может выполнять синтаксический анализ сложных DTD. Этим парсером также формируется гораздо более детальное представление документа XML, включающее инструкции обработки и URI пространств имен, относящиеся к элементам и атрибутам. Очень важно то, что он предоставляет доступ к информации через интерфейс, описанный в спецификации W3C DOM.
Спецификация W3C, которая все еще дорабатывается, имеет несколько «уровней»; в настоящее время предусматривается три уровня. Классы DOMImplementation
, DOMDocument
, DOMElement
и DOMNodeList
, использованные в примере 14.10, описываются на уровне 1 спецификации DOM. Классы DOMBuilder
и DOMWrite
описываются на уровне 3 спецификации DOM как часть рекомендаций по функции загрузки и сохранения (Load и Save).
Имена классов Xerces не всегда совладают с именами интерфейсов W3C DOM, которые они реализуют; это происходит из-за того, что Xerces реализует несколько спецификаций в одном пространстве имен и использует префиксы в именах классов, чтобы избежать конфликтов имен.
Понимание примера 14.10 теперь не должно вызывать затруднений. Я начинаю с инициализации Xerces, как это делается в примере 14.8. Затем я получаю DOMImplementation
из DOMImplementationRegistry
, запрашивая функцию загрузки и сохранения путем передачи строки «LS
» статическому методу DOMImplementationRegistry::getDOMImplementation()
. На следующем шаге я получаю DOMBuilder
из DOMImplementation
. Мне приходится тип DOMImplementation
привести к типу DOMImplementationLS
, потому что функция загрузки и сохранения недоступна из интерфейса DOMImplementation
согласно спецификации W3C DOM уровня 1. Первый аргумент createDOMBuilder()
показывает, что возвращаемый парсер будет работать в
Получив DOMBuilder
, я включаю поддержку пространства имен XML, регистрирую обработчик ErrorHandler
и выполняю синтаксический анализ документа. Парсер возвращает документ в виде DOMDocument
; используя метод getElementsByTagName()
документа DOMDocument
, я получаю объект DOMElement
, соответствующий элементу этого документа animalList
, и просматриваю его дочерние элементы, используя объект типа DOMNodeList
. Когда я нахожу элемент, имеющий дочерний элемент типа name
и содержащий текст «Herby
», я удаляю его из документа с помощью