System.Xml.Schema.XmlSchemaSet 类

本文提供了此 API 参考文档的补充说明。

重要

  • 请勿使用来自未知或不受信任的源或位置的架构。 这样做会损害代码的安全性。
  • XSD 架构(包括内联架构)从本质上就容易受到拒绝服务攻击,因此请不要接受不受信任场景中的 XSD 架构。
  • 架构验证错误消息和异常可能会公开有关架构文件的内容模型或 URI 路径的敏感信息。 请注意不要向不受信任的调用方公开此信息。
  • “安全注意事项”部分介绍了其他安全注意事项。

XmlSchemaSet 是可以存储 XML 架构定义语言 (XSD) 架构的缓存或库。 XmlSchemaSet 在内存中缓存架构,而不是通过文件或 URL 访问架构,从而提升了性能。 每个架构通过命名空间 URI 和位置来标识,命名空间 URI 和位置在架构添加到集时指定。 可以使用 XmlReaderSettings.Schemas 属性分配 XML 读取器应在数据验证中使用的 XmlSchemaSet 对象。

安全注意事项

  • 不要使用来自未知或不受信任的源的架构。 这样做会损害代码的安全性。 架构的 include、import 和 redefine 元素中引用的外部命名空间或位置是根据包含或导入它们的架构的基本 URI 来解析的。 例如,如果包含或导入架构的基本 URI 为空或 null,则外部位置将根据当前目录进行解析。 默认情况下,XmlUrlResolver 类将用于解析外部架构。 若要禁用对架构的 include、import 和 redefine元素的解析,请将 XmlSchemaSet.XmlResolver 属性设置为 null

  • XmlSchemaSet 类使用 System.Text.RegularExpressions.Regex 类来分析和匹配 XML 架构中的正则表达式。 在 XML 架构中使用正则表达式验证模式面可能会增加 CPU 的使用率,在高可用性场景中应避免这样做。

  • 由于使用 XmlSchemaSet 类而引发的异常(例如 XmlSchemaException 类)可能包含不应在不受信任的场景中公开的敏感信息。 例如,XmlSchemaExceptionSourceUri 属性会返回导致异常的架构文件的 URI 路径。 不应在不受信任的场景中公开 SourceUri 属性。 应正确处理异常,以免在不受信任的场景中公开此敏感信息。

示例

以下示例使用 XmlSchemaSet 中存储的架构验证 XML 文件。 XML 文件 urn:bookstore-schema 中的命名空间标识 XmlSchemaSet 中要用于验证的架构。 示例输出显示 XML 文件有两个架构冲突:

  • 第一个 <book> 元素包含 <author> 元素,但不包含 <title> 或 <price> 元素。

  • 最后一个 <book> 元素中的 <author> 元素缺少 <first-name> 和 <last-name> 元素,但却包含有效的 <name> 元素。

using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;

public class Sample
{
  public static void Main() {

    // Create the XmlSchemaSet class.
    XmlSchemaSet sc = new XmlSchemaSet();

    // Add the schema to the collection.
    sc.Add("urn:bookstore-schema", "books.xsd");

    // Set the validation settings.
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.Schemas = sc;
    settings.ValidationEventHandler += ValidationCallBack;

    // Create the XmlReader object.
    XmlReader reader = XmlReader.Create("booksSchemaFail.xml", settings);

    // Parse the file.
    while (reader.Read());
  }

  // Display any validation errors.
  private static void ValidationCallBack(object sender, ValidationEventArgs e) {
    Console.WriteLine($"Validation Error:\n   {e.Message}\n");
  }
}
// The example displays output like the following:
//   Validation Error:
//        The element 'book' in namespace 'urn:bookstore-schema' has invalid child element 'author'
//        in namespace 'urn:bookstore-schema'. List of possible elements expected: 'title' in
//        namespace 'urn:bookstore-schema'.
//
//    Validation Error:
//       The element 'author' in namespace 'urn:bookstore-schema' has invalid child element 'name'
//       in namespace 'urn:bookstore-schema'. List of possible elements expected: 'first-name' in
//       namespace 'urn:bookstore-schema'.
Imports System.Xml
Imports System.Xml.Schema
Imports System.IO

Public Module Sample 
  Public Sub Main() 

    ' Create the XmlSchemaSet class.
    Dim sc as XmlSchemaSet = new XmlSchemaSet()

    ' Add the schema to the collection.
    sc.Add("urn:bookstore-schema", "books.xsd")

    ' Set the validation settings.
    Dim settings as XmlReaderSettings = new XmlReaderSettings()
    settings.ValidationType = ValidationType.Schema
    settings.Schemas = sc
    AddHandler settings.ValidationEventHandler, AddressOf ValidationCallBack
 
    ' Create the XmlReader object.
    Dim reader as XmlReader = XmlReader.Create("booksSchemaFail.xml", settings)

    ' Parse the file. 
    While reader.Read()
    End While
    
  End Sub

  ' Display any validation errors.
  Private Sub ValidationCallBack(sender as object, e as ValidationEventArgs) 
    Console.WriteLine($"Validation Error:{vbCrLf}   {e.Message}")
    Console.WriteLine()
  End Sub
End Module
' The example displays output like the following:
'   Validation Error: 
'        The element 'book' in namespace 'urn:bookstore-schema' has invalid child element 'author' 
'        in namespace 'urn:bookstore-schema'. List of possible elements expected: 'title' in 
'        namespace 'urn:bookstore-schema'.
'
'    Validation Error: 
'       The element 'author' in namespace 'urn:bookstore-schema' has invalid child element 'name' 
'       in namespace 'urn:bookstore-schema'. List of possible elements expected: 'first-name' in 
'       namespace 'urn:bookstore-schema'.

输入

示例使用下列两个输入文件。

booksSchemaFail.xml:

<?xml version='1.0'?>
<bookstore xmlns="urn:bookstore-schema">
  <book>
    <author>
      <first-name>Benjamin</first-name>
      <last-name>Franklin</last-name>
    </author>
  </book>
  <book genre="novel">
    <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">
    <title>The Gorgias</title>
    <author>
      <name>Plato</name>
    </author>
    <price>9.99</price>
  </book>
</bookstore>

books.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="urn:bookstore-schema"
    elementFormDefault="qualified"
    targetNamespace="urn:bookstore-schema">

 <xsd:element name="bookstore" type="bookstoreType"/>

 <xsd:complexType name="bookstoreType">
  <xsd:sequence maxOccurs="unbounded">
   <xsd:element name="book"  type="bookType"/>
  </xsd:sequence>
 </xsd:complexType>

 <xsd:complexType name="bookType">
  <xsd:sequence>
   <xsd:element name="title" type="xsd:string"/>
   <xsd:element name="author" type="authorName"/>
   <xsd:element name="price"  type="xsd:decimal"/>
  </xsd:sequence>
  <xsd:attribute name="genre" type="xsd:string"/>
 </xsd:complexType>

 <xsd:complexType name="authorName">
  <xsd:sequence>
   <xsd:element name="first-name"  type="xsd:string"/>
   <xsd:element name="last-name" type="xsd:string"/>
  </xsd:sequence>
 </xsd:complexType>

</xsd:schema>