XML校验学习之一:使用XSD模式验证XML数据

 

XML文档包括了元素、属性和基本数据类型的值。在全章中,将使用一个名为Authors.xmlXML文档,该文档显示于程序清单5-1

程序清单5-1  Authors.xml文件

<?xml version="1.0"?>

<authors>

  <author>

    <au_id>172-32-1176</au_id>

    <au_lname>White</au_lname>

    <au_fname>Johnson</au_fname>

    <phone>408 496-7223</phone>

    <address>10932 Bigge Rd.</address>

    <city>Menlo Park</city>

    <state>CA</state>

    <zip>94025</zip>

    <contract>true</contract>

  </author>

  <author>

    <au_id>213-46-8915</au_id>

    <au_lname>Green</au_lname>

    <au_fname>Marjorie</au_fname>

    <phone>415 986-7020</phone>

    <address>309 63rd St. #411</address>

    <city>Oakland</city>

    <state>CA</state>

    <zip>94618</zip>

    <contract>true</contract>

  </author>

</authors>

XSD模式定义了元素、属性以及它们之间的关系。它符合W3CXML模式标准和建议标准。Authors.xml文档的XSD模式是Authors.xsd,显示在程序清单5-2中。

程序清单5-2  Authors.xsd文件

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

<xs:schema attributeFormDefault="unqualified" elementFormDefault

       ="qualified"  

  xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="authors">

    <xs:complexType>

      <xs:sequence>

        <xs:element maxOccurs="unbounded" name="author">

          <xs:complexType>

            <xs:sequence>

              <xs:element name="au_id" type="xs:string" />

              <xs:element name="au_lname" type="xs:string" />

              <xs:element name="au_fname" type="xs:string" />

              <xs:element name="phone" type="xs:string" />

              <xs:element name="address" type="xs:string" />

              <xs:element name="city" type="xs:string" />

              <xs:element name="state" type="xs:string" />

              <xs:element name="zip" type="xs:unsignedInt" />

              <xs:element name="contract" type="xs:boolean" />

            </xs:sequence>

          </xs:complexType>

        </xs:element>

      </xs:sequence>

    </xs:complexType>

  </xs:element>

</xs:schema>

.NET Framework 2.0类支持W3C XML模式建议标准。一般部署的用来验证XML文档的类有XmlReaderXmlReaderSettingsXmlSchemaSetXmlNodeReader。使用XSD模式进行XML文档验证的步骤顺序如下。

1. 验证XML文档的步骤

(1) 定义一个ValidationEventHandler事件处理程序方法。

(2) 创建XmlReaderSettings对象的实例。XmlReaderSettings类允许指定一套由XmlReader对象支持的选项,并且这些选项将会在解析XML数据的时候起作用。请注意XmlReaderSettings生成废弃的XmlValidatingReader(用于.NET 1.x版本)

(3) 将前面定义好的ValidationEventHandler方法与XmlReaderSettings类相关联。

(4) XmlReaderSettingsValidationType属性设置为ValidationType.Schema

(5) XmlReaderSettings类的Schema属性将XSD模式添加至XmlReaderSettings类。

(6) 在解析XML数据的时候,XmlReader类使用Read方法验证XML文档。

验证事件处理程序

ValidationEventHandler事件定义了一个事件处理程序,用于接收关于XSD模式验证错误的通知。验证的错误和警告通过ValidationEventHandler回调函数来报告。验证错误不会停止解析,解析只会在XML文档不是格式良好时停止。但是,如果您没有提供验证事件处理程序的回调函数并且发生了验证错误,将会抛出异常。使用验证事件回调机制捕获所有验证错误的这种方式可以在单步过程中发现所有的验证错误。

XML验证中XmlReaderSettings类的角色

XmlReaderSettings类和XmlReader类一样是最重要的类之一,它提供了验证XML数据的核心基础。表5-1提供了XmlReaderSettings类中验证相关属性的简要描述,本章后部分将会利用这些属性。

 

 

5-1  验证X mlReaderSettings类的相关属性和事件

   

   

ProhibitDtd

指示XmlReaderSettings类是否支持DTD验证。默认值是true,表示不支持DTD验证

ValidationType

指定XmlReaderSettings类支持的验证类型。允许的验证类型是DTDXSDNone

ValidationEventHandler

指定事件处理程序,用于接收关于验证事件的信息

ValidationFlags

指定在验证XML数据时将被强制执行的附加的验证设置,如使用内嵌模式、身份约束和XML属性

Schemas

获得或者设置XmlSchemaSet对象,该对象表示用于执行模式验证的模式集合

 

为了能够使用XmlReaderSettings类来验证XML数据,必须将XmlReaderSettings类的属性设置为正确的值。这个类本身无法运行,而需要与XmlReader或者XmlNodeReader实例一同运行。您可以使用这个类并依据DTDXML模式进行验证。

2. 一个XML验证的示例

既然您对XML数据的验证步骤有了一个大概的了解,那么现在就来看一个示例并理解它是如何实际工作的。程序清单5-3利用Authors.xsd模式文件来验证Authors.xml文件。

程序清单5-3  使用XSD模式验证XML数据

<%@ Page Language="C#"%>

<%@ Import Namespace="System.Xml" %>

<%@ Import Namespace="System.Xml.Schema" %>

<script runat="server">   

  private StringBuilder _builder = new StringBuilder();

  void Page_Load(object sender, EventArgs e)

  {

    string xmlPath = Request.PhysicalApplicationPath +

      @""App_Data"Authors.xml";   

    string xsdPath = Request.PhysicalApplicationPath +

      @""App_Data"Authors.xsd";

    XmlReader reader = null;       

    XmlReaderSettings settings = new XmlReaderSettings();

    settings.ValidationEventHandler += new

      ValidationEventHandler(this.ValidationEventHandler);

    settings.ValidationType = ValidationType.Schema;       

    settings.Schemas.Add(null, XmlReader.Create(xsdPath));

    reader = XmlReader.Create(xmlPath, settings);

    while (reader.Read())

    {           

    }

    if (_builder.ToString() == String.Empty)

      Response.Write("Validation completed successfully.");

    else

      Response.Write("Validation Failed. <br>" + _builder.ToString());

    }

 

  void ValidationEventHandler(object sender, ValidationEventArgs args)

  {       

    _builder.Append("Validation error: " + args.Message + "<br>");               

  }     

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

  <title>XSD Validation</title>

</head>

<body>

  <form id="form1" runat="server">

    <div>               

    </div>

  </form>

</body>

</html>

在研究以上代码之前,图5-1显示了由程序清单5-3生成的输出。

  5-1

在代码开始处,程序清单5-3声明了用于保存XMLXSD模式文件路径的变量。然后创建了XmlReaderSettings对象的实例并将其与验证事件处理程序的回调方法相关联。

XmlReaderSettings settings = new XmlReaderSettings();

settings.ValidationEventHandler += new

  ValidationEventHandler(this.ValidationEventHandler);

然后,它将XmlReaderSettings类的ValidationType属性设置为ValidationType.Schema,通知XmlReader对象在解析XML数据的时候使用所提供的XSD模式进行XML数据验证。

    settings.ValidationType = ValidationType.Schema;       

除了模式之外,ValidationType枚举还支持其他值,这些值列在表5-2中。

5-2  ValidationiType枚举值

   

DTD

指示将使用DTD执行验证

None

不执行验证,也不抛出验证错误

Schema

根据XML模式(包括内嵌的XSD模式)验证XML文档

 

随后代码将Authors.xsd文件添加至XmlReaderSettings对象的模式集合。此后,它会调用XmlReader对象的静态Create方法并传入Authors.xml文件的路径和XmlReaderSettings对象。Create方法返回XmlReader对象的实例,该实例就会在分析文档的时候使用DTDXML模式执行验证。

settings.Schemas.Add(null, XmlReader.Create(xsdPath));

reader = XmlReader.Create(xmlPath, settings);

因为XmlReader对象是通过在Create方法中传入XmlReaderSettings对象而创建的,所以XmlReaderSettings中的设置将被XmlReader对象支持。然后在While循环中调用XmlReader对象的Read方法来读取并验证整个XML文件。只要发生验证错误就会调用ValidationEventHandler方法。在这个方法中,StringBuilder对象一直将验证错误消息内容添加至本身。如果没有提供验证事件处理程序,那么当出现验证错误的时候就会抛出XmlSchemaException异常。

3. 处理XML验证中的异常

在程序清单5-3中,只要出现了XML验证错误,控制就会自动转向ValidationEventHandler方法,来处理异常并将验证错误消息(通过ValidationEventArgs对象的Message属性获得)添加至StringBuilder对象。如果StringBuilder对象包含了所有消息,最后这个错误消息将会显示给用户。虽然这对本示例来说已经足够,但是很多时候您会想要区分不同的异常类型,如在验证过程中产生的警告或者错误。为了达到这个目的,可以检查ValidationEventArgs对象的Severity属性。这个属性返回XmlSeverityType类的枚举,可用于判断产生的异常类型。表5-3显示了这个枚举所包含的值。

5-3  XmlSeverityType枚举值

   

Error

指示在验证实例文档时出现了验证错误。这可以是使用DTDXSD模式的验证结果。如果没有验证事件处理程序来处理这种情况,将会抛出异常

Warning

指示验证解析器已经运行到一个没有错误但是有必要警告用户的情况之下。WarningError的不同之处是它不会在调用方法的应用程序中抛出异常

 

例如,如果只想过滤在验证过程中产生的错误,则可以通过使用如下代码来达到这个目的。

private void ValidationEventHandler(object sender, ValidationEventArgs args)

{

  if (args.Severity == XmlSeverityType.Error)

  {

    //Add code to handle the errors

  }

}

posted @ 2009-02-18 18:55  catch22  阅读(6484)  评论(0编辑  收藏  举报