XmlDocument使用类,可以通过两种方式验证对象中包含的 XmlDocument XML 内容。 第一种方法是使用验证对象 XmlReader 来验证 XML 内容,第二种方法是使用类 Validate 的 XmlDocument 方法。 还可以使用 XPathDocument 类对 XML 内容执行只读验证。
验证 XML 数据
默认情况下,该 XmlDocument 类不会使用 DTD 或 XML 架构定义语言 (XSD) 架构验证来验证 XML 文档。 它仅验证 XML 文档的格式正确。
验证 XML 文档的第一种方法是将文档加载到XmlDocument对象中时使用XmlReader对象进行验证。 第二种方法是使用 Validate 类的方法验证以前未键入的 XmlDocument XML 文档。 在这两种情况下,可以使用 Validate 类的 XmlDocument 方法重新验证对已验证的 XML 文档的更改。
在文档加载时进行验证
通过将XmlReader对象传递给类XmlReaderSettings的Create方法,该方法以XmlReader对象作为参数,可以创建验证XmlReaderSettings对象。 传递为参数的XmlReaderSettings对象有一个ValidationType属性,其值为Schema
,并且将XmlDocument对象中包含的 XML 文档的 XML 架构添加到了Schemas属性中。 然后,验证 XmlReader 对象用于创建 XmlDocument 对象。
以下示例在 contosoBooks.xml
文件加载到 XmlDocument 对象时进行验证,方法是使用验证 XmlDocument 对象创建 XmlReader 对象。 由于 XML 文档根据其架构有效,因此不会生成架构验证错误或警告。
Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
Class ValidatingReaderExample
Shared Sub Main(ByVal args() As String)
Try
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
settings.ValidationType = ValidationType.Schema
Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)
Dim document As XmlDocument = New XmlDocument()
document.Load(reader)
Dim navigator As XPathNavigator = document.CreateNavigator()
Catch e As Exception
Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message)
End Try
End Sub
Shared Sub SchemaValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)
Select Case e.Severity
Case XmlSeverityType.Error
Console.WriteLine("Schema Validation Error: {0}", e.Message)
Exit Sub
Case XmlSeverityType.Warning
Console.WriteLine("Schema Validation Warning: {0}", e.Message)
Exit Sub
End Select
End Sub
End Class
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
class ValidatingReaderExample
{
static void Main(string[] args)
{
try
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
settings.ValidationType = ValidationType.Schema;
XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);
XmlDocument document = new XmlDocument();
document.Load(reader);
XPathNavigator navigator = document.CreateNavigator();
}
catch (Exception e)
{
Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message);
}
}
static void SchemaValidationHandler(object sender, ValidationEventArgs e)
{
switch (e.Severity)
{
case XmlSeverityType.Error:
Console.WriteLine("Schema Validation Error: {0}", e.Message);
break;
case XmlSeverityType.Warning:
Console.WriteLine("Schema Validation Warning: {0}", e.Message);
break;
}
}
}
该示例将 contosoBooks.xml
文件作为输入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
该示例还将 contosoBooks.xsd
作为输入。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="author">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
<xs:element minOccurs="0" name="first-name" type="xs:string" />
<xs:element minOccurs="0" name="last-name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
<xs:attribute name="genre" type="xs:string" use="required" />
<xs:attribute name="publicationdate" type="xs:date" use="required" />
<xs:attribute name="ISBN" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
在上面的示例中,当调用XmlSchemaValidationException时,如果任何属性或元素类型与验证架构中指定的相应类型不匹配,则会抛出Load。 如果在验证ValidationEventHandler上设置了XmlReader,那么每当遇到无效类型时,都会调用ValidationEventHandler。
由 XmlSchemaException 访问 TypedValue 设置为 invalid
的属性或元素时,将引发 XPathNavigator。
在使用 Validity 访问属性或元素时,可以使用 XPathNavigator 属性来判断单个属性或元素是否有效。
注释
当将 XML 文档加载到带有定义默认值的关联架构的 XmlDocument 对象中时,XmlDocument 对象会将这些默认值视同为实际存在于 XML 文档中的内容。 这意味着,对于在架构中默认的元素,即使在 XML 文档中将其写入为空元素,IsEmptyElement 属性也始终返回 false
。
使用 Validate 方法验证文档
Validate 类的 XmlDocument 方法针对 XmlDocument 对象的 XmlDocument 属性中指定的架构验证 Schemas 对象中包含的 XML 文档,然后执行信息集增加。 结果是对象中的 XmlDocument 未加类型的 XML 文档被替换为类型化文档。
XmlDocument 对象使用作为参数传递给 ValidationEventHandler 方法的 Validate 委托报告架构验证错误和警告。
以下示例针对 contosoBooks.xml
对象的 XmlDocument 属性中包含的 contosoBooks.xsd
架构验证 XmlDocument 对象中包含的 Schemas 文件。
Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
Class ValidateExample
Shared Sub Main(ByVal args() As String)
Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
Dim validation As ValidationEventHandler = New ValidationEventHandler(AddressOf SchemaValidationHandler)
document.Validate(validation)
End Sub
Shared Sub SchemaValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)
Select Case e.Severity
Case XmlSeverityType.Error
Console.WriteLine("Schema Validation Error: {0}", e.Message)
Exit Sub
Case XmlSeverityType.Warning
Console.WriteLine("Schema Validation Warning: {0}", e.Message)
Exit Sub
End Select
End Sub
End Class
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
class ValidateExample
{
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();
document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
ValidationEventHandler validation = new ValidationEventHandler(SchemaValidationHandler);
document.Validate(validation);
}
static void SchemaValidationHandler(object sender, ValidationEventArgs e)
{
switch (e.Severity)
{
case XmlSeverityType.Error:
Console.WriteLine("Schema Validation Error: {0}", e.Message);
break;
case XmlSeverityType.Warning:
Console.WriteLine("Schema Validation Warning: {0}", e.Message);
break;
}
}
}
该示例将 contosoBooks.xml
文件作为输入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
该示例还将 contosoBooks.xsd
作为输入。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="author">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
<xs:element minOccurs="0" name="first-name" type="xs:string" />
<xs:element minOccurs="0" name="last-name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
<xs:attribute name="genre" type="xs:string" use="required" />
<xs:attribute name="publicationdate" type="xs:date" use="required" />
<xs:attribute name="ISBN" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
验证修改
对 XML 文档进行修改后,可以使用Validate方法验证这些修改是否符合 XML 文档的XmlDocument模式。
以下示例在 contosoBooks.xml
文件加载到 XmlDocument 对象时进行验证,方法是使用验证 XmlDocument 对象创建 XmlReader 对象。 XML 文档在加载时成功验证,而不会生成任何架构验证错误或警告。 该示例首先对 contosoBooks.xsd
架构的 XML 文档进行了两次修改,这些修改使文档变得无效。 第一次修改插入无效的子元素,导致架构验证错误,第二次修改会将类型化节点的值设置为根据导致异常的节点类型无效的值。
Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.XPath
Class ValidatingReaderExample
Shared Sub Main(ByVal args() As String)
Try
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
settings.ValidationType = ValidationType.Schema
Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)
Dim document As XmlDocument = New XmlDocument()
document.Load(reader)
Dim navigator As XPathNavigator = document.CreateNavigator()
Dim validation As ValidationEventHandler = New ValidationEventHandler(AddressOf SchemaValidationHandler)
navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.MoveToChild("author", "http://www.contoso.com/books")
navigator.AppendChild("<title>Book Title</title>")
document.Validate(validation)
navigator.MoveToParent()
navigator.MoveToChild("price", "http://www.contoso.com/books")
navigator.SetTypedValue(DateTime.Now)
Catch e As Exception
Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message)
End Try
End Sub
Shared Sub SchemaValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)
Select Case e.Severity
Case XmlSeverityType.Error
Console.WriteLine("Schema Validation Error: {0}", e.Message)
Exit Sub
Case XmlSeverityType.Warning
Console.WriteLine("Schema Validation Warning: {0}", e.Message)
Exit Sub
End Select
End Sub
End Class
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
class ValidatingReaderExample
{
static void Main(string[] args)
{
try
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
settings.ValidationType = ValidationType.Schema;
XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);
XmlDocument document = new XmlDocument();
document.Load(reader);
XPathNavigator navigator = document.CreateNavigator();
ValidationEventHandler validation = new ValidationEventHandler(SchemaValidationHandler);
navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.MoveToChild("author", "http://www.contoso.com/books");
navigator.AppendChild("<title>Book Title</title>");
document.Validate(validation);
navigator.MoveToParent();
navigator.MoveToChild("price", "http://www.contoso.com/books");
navigator.SetTypedValue(DateTime.Now);
}
catch (Exception e)
{
Console.WriteLine("ValidatingReaderExample.Exception: {0}", e.Message);
}
}
static void SchemaValidationHandler(object sender, ValidationEventArgs e)
{
switch (e.Severity)
{
case XmlSeverityType.Error:
Console.WriteLine("Schema Validation Error: {0}", e.Message);
break;
case XmlSeverityType.Warning:
Console.WriteLine("Schema Validation Warning: {0}", e.Message);
break;
}
}
}
该示例将 contosoBooks.xml
文件作为输入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
该示例还将 contosoBooks.xsd
作为输入。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="author">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
<xs:element minOccurs="0" name="first-name" type="xs:string" />
<xs:element minOccurs="0" name="last-name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
<xs:attribute name="genre" type="xs:string" use="required" />
<xs:attribute name="publicationdate" type="xs:date" use="required" />
<xs:attribute name="ISBN" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
在上面的示例中,对对象中包含的 XmlDocument XML 文档进行了两次修改。 加载 XML 文档时,遇到的任何架构验证错误都将由验证事件处理程序方法处理,并写入控制台。
在此示例中,加载 XML 文档之后引入验证错误,并使用 Validate 类的 XmlDocument 方法发现错误。
使用 SetTypedValue 类的 XPathNavigator 方法进行的修改引发了 InvalidCastException,因为新值不符合节点的架构类型。
有关使用 SetTypedValue 该方法修改值的详细信息,请参阅 使用 XPathNavigator 主题修改 XML 数据 。
只读验证
该 XPathDocument 类是 XML 文档的只读内存中表示形式。 类 XPathDocument 和 XmlDocument 类都创建 XPathNavigator 对象来导航和编辑 XML 文档。 由于 XPathDocument 类是只读类,XPathNavigator 对象无法编辑从 XPathDocument 对象返回的 XPathDocument 对象中包含的 XML 文档。
在验证时,可以创建一个 XPathDocument 对象,就好像使用验证 XmlDocument 对象创建 XmlReader 对象一样,如本主题前面所述。 对象 XPathDocument 在加载 XML 文档时验证 XML 文档,但由于不能编辑对象 XPathDocument 中的 XML 数据,因此无法重新验证 XML 文档。
有关只读和可 XPathNavigator 编辑对象的详细信息,请参阅 使用 XPathDocument 和 XmlDocument 主题读取 XML 数据 。