首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

14.5 使用DTD验证一个XML文档

问题

如何根据一个DTD来验证一个XML文档?

解决方案

使用Xerces类库中的SAX2(XML的简单API)或者DOM解析器。

为了使用SAX2来验证XML文档,你需要获取一个SAX2XMLReader,如示例14-8中那样。接下来,通过参数xercesc::XMLUni::fgSAX2CoreValidation和true来调用解析器的setFeature()方法打开DTD合法性验证功能。最后,注册一个ErrorHandler方法来接收DTD违反通知,并且以你的XML文档名作为参数来调用解析器的parse()方法。

为了使用DOM来验证XML文档,首先你需要构造一个XercesDOMParser实例。接下来,以参数xercesc::XercesDOMParser::Val_Always调用解析器的setValidationScheme()方法来打开DTD验证功能。最后,注册一个ErrorHandler类接收DTD违反通知,并且使用你的XML文档名作为参数来调用这个解析器的parse()方法。

注意:    这里我使用类XercesDOMParser,这个解析器是Xerces的一部分,这个部分是在DOM3标准的DOMBuilder接口之前引入的。使用XercesDOMParser更简单,但是你还是可以使用DOMBuilder。请参考14.4节的讨论。

例如,假设你想修改来自示例14-1中的XML文档animals.xml使得它包含一个外在的DTD引用,如示例14-11和14-12中说明的那样。使用SAX2 API来验证这个XML文档的合法性的代码在示例14-13中;而使用DOM解析器来验证这个XML文档的代码在示例14-14中。

示例14-11  XML文档animals.xml的DTD animals.dtd文件

<!-- DTD for Feldman Family Circus Animals -->

<!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 修改后的包含DTD的animals.xml文档

<?xml version="1.0" encoding="UTF-8"?>

<!-- Feldman Family Circus Animals with DTD -->

<!DOCTYPE animalList SYSTEM "animals.dtd">

    <!-- same as Example 14-1 -->

</animalList>

示例14-13  使用SAX2 API来验证animals.xml的DTD的合法性

/*

 * Same includes as Example 14-8, except <vector> is not needed

 */

#include <stdexcept> // runtime_error

#include <xercesc/sax2/DefaultHandler.hpp>

using namespace std;

using namespace xercesc;

/*

 * Define XercesInitializer as in Example 14-8

 * and CircusErrorHandler as in Example 14-7

 */

int main()

{

    try {

        // Initialize Xerces and obtain a SAX2 parser

        XercesInitializer init;

        auto_ptr<SAX2XMLReader> 

            parser(XMLReaderFactory::createXMLReader());

        // Enable validation

        parser->setFeature(XMLUni::fgSAX2CoreValidation, true);

        // Register error handler to receive notifications

        // of DTD violations

        CircusErrorHandler error;

        parser->setErrorHandler(&error);

        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;

    }

}

示例14-14  使用XercesDOMParser来验证这个animals.xml文档的DTD animals.dtd的合法性

#include <exception>

#include <iostream>// cout

#include <stdexcept>    // runtime_error

#include <xercesc/dom/DOM.hpp>

#include <xercesc/parsers/XercesDOMParser.hpp>

#include <xercesc/sax/HandlerBase.hpp>

#include <xercesc/util/PlatformUtils.hpp>

#include "xerces_strings.hpp"  // Example 14-4

using namespace std;

using namespace xercesc;

/*

 * Define XercesInitializer as in Example 14-8

 * and CircusErrorHandler as in Example 14-7

 */

int main()

{

    try {

        // Initialize Xerces and construct a DOM parser.

        XercesInitializer   init;

        XercesDOMParserparser;

        // Enable DTD validation

        parser.setValidationScheme(XercesDOMParser::Val_Always);

        // Register an error handler to receive notifications

        // of schema violations

        CircusErrorHandler  handler;

        parser.setErrorHandler(&handler);

        // Parse and validate.

        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;

    }

}

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论