len = animals->getLength(); i < len; ++i) {
DOMElement* animal =
static_cast(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 writer =
static cast(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()) << "\n";
return EXIT_FAILURE;
} catch (const DOMException& e) {
cout << "xml error: " << toNative(e.getMessage()) << "\n";
return EXIT_FAILURE;
} catch (const exception& e) {
cout << e.what() << "\n";
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()показывает, что возвращаемый парсер будет работать в синхронном режиме . Другой возможный режим, а именно асинхронный режим , в настоящее время не поддерживается в Xerces.
Получив DOMBuilder, я включаю поддержку пространства имен 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.
Читать дальше