Пример 14.18. Подтверждение соответствия документа XML внешней схеме, используя DOM
/*
* Те же самые операторы #include, которые использовались в примере 14.14
*/
using namespace std;
using namespace xercesc;
/*
* Определить XercesInitializer, как в примере 14.8,
* и CircusErorHandler, как в примере 14.7
*/
int main() {
try {
// Инициализировать Xerces и сконструировать парсер DOM.
XercesInitializer init;
XercesDOMParser parser;
// Включить проверку
parser.setValidationScheme(XercesDOMParser::Val_Always);
parser.setDoSchema(true); parser.setDoNamespaces(true);
parser.setExternalNoNamespaceSchemaLocation(
fromNative("animals.xsd").c_str());
// Зарегистрировать обработчик ошибок для получения уведомлений о
// нарушениях схемы
CircusErrorHandler handler;
parser.setErrorHandler(&handler);
// Выполнить синтаксический анализ и проверить соответствие документа
// схеме.
parser parse("animals.xml");
} catch (const SAXException& e) {
cout << "xml error: " << toNative(e.getMessage()) << "\n";
return EXIT_FAILURE;
} catch (const XMLException& e) {
cout << "xml error: " << toNative(e.getMessage()) << "\n";
return EXIT_FAILURE;
} catch (const exception& e) {
cout << e.what() << "\n";
return EXIT_FAILURE;
}
}
Подобно определениям DTD, рассмотренным в предыдущем рецепте, схемы накладывают ограничения на документы XML. Схема предназначена для определения подмножества правильно сформированных документов, характерных для определенной прикладной области. Однако схемы имеют три отличия от определений DTD. Во-первых, концепция DTD и связанное с ней понятие подтверждения достоверности (validity) определены в самой спецификации XML, в то время как схемы описаны в другой спецификации — в рекомендациях XML Schema. Во-вторых, сами схемы являются правильно сформированными документами XML, в то время как для описания определений DTD используется специальный синтаксис, продемонстрированный в примере 14.11. В-третьих, схемы существенно более выразительны, чем определения DTD. Из-за двух последних отличий считается, что схемы превосходят определения DTD.
Например, в DTD из примера 14.11 можно было лишь потребовать, чтобы элементы veterinarian
имели ровно два атрибута, name
и phone
, значения которых состоят из символов. Напротив, схема в примере 14.16 требует, чтобы значение атрибута phone
, кроме того, соответствовало регулярному выражению \(\d{3}\)\d{3}-\d{4}
, т.е. чтобы оно имело вид (ddd)xxx-dddd
, где d
может быть любой цифрой. Аналогично обстоит дело с элементом dateOfBirth
: если в DTD можно было только потребовать, чтобы этот элемент имел текстовое значение, то схема требует, чтобы текстовое значение имело вид yyyy-mm-dd
, где yyyy
задается в диапазоне от 0001 до 9999, mm
— от 01 до 12, a dd
— от 01 до 31.
Способность накладывать эти дополнительные ограничения создает большое преимущество, поскольку позволяет часть программистской работы переложить на парсер.
Рецепт 14.5.
14.7. Преобразование документа XML с помощью XSLT
Требуется преобразовать документ XML, используя таблицу стилей XSLT.
Используйте библиотеку Xalan. Во-первых, сконструируйте экземпляр конвертора XSTL xalanc::XalanTransformer
. Затем сконструируйте два экземпляра xalanc::XSLTInputSource
(один для документа, который будет преобразован, а другой для вашей таблицы стилей) и экземпляр хаlanc::XSLTResultTarget
для документа, который будет получен в результате преобразования. Наконец, вызовите метод XSLT transform()
, передавая в качестве аргументов два экземпляра XSLTInputSource
и один XSLTResultTarget
.
Например, представим, что требуется с помощью веб-браузера просматривать список животных цирка из примера 14.1. Это легко сделать с помощью XSLT В примере 14.19 приводится таблица стилей XSLT, которая на входе принимает документ XML, такой как animals.xml, и формирует документ HTML, содержащий таблицу, в каждой строке которой описывается одно животное с указанием клички, вида, даты рождения, ветеринара и дрессировщика. Пример 14.20 показывает, как можно использовать библиотеку Xalan, чтобы воспользоваться этой таблицей стилей для документа animals.xml. В примере 14.21 приводится HTML, сгенерированный программой из примера 14.20; этот HTML переформатирован для лучшего восприятия.
Пример 14.19. Таблица стилей для animals.xml
<?xml version="1.0" encoding="utf-8"?>
<!- Таблица стилей для животных цирка Feldman Family Circus -->
<xsclass="underline" stylesheet versions="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsclass="underline" output method="html"/>
<xsclass="underline" template match="/">
<html>
<head>
<title>Feldman Family Circus Animals</title>
</head>
<body>
<h1>Feldman Family Circus Animals</h1>
<table cellpadding="3" border="1">
<tr>
<th>Name</th>
<th>Species</th>
<th>Date of Birth</th>
<th>Veterinarian</th>
<th>Trainer</th>
</tr>
<xsclass="underline" apply-templates match="animal">
</xsclass="underline" apply-templates>
</table>
</body>
</html>
</xsclass="underline" template>
<xsclass="underline" template match="animal">
<tr>
<td><xsclass="underline" value-of select="name"/></td>
<td><xsclass="underline" value-of select="species"/></td>
<td><xsclass="underline" value-of select="dateOfBirth"/></td>
<xsclass="underline" apply-templates select="veterinarian"/>
<xsclass="underline" apply-templates select="trainer"/>
</tr>
</xsclass="underline" template>
<xsclass="underline" template match="veterinarian|trainer">
<td>
<table>
<tr>