System.Xml.Schema.XmlSchemaSet クラス

この記事は、この API のリファレンス ドキュメントの補足説明です。

重要

  • 不明または信頼されていないソースや場所のスキーマは使用しないでください。 これを行うと、コードのセキュリティが損なわれます。
  • XML スキーマ (インライン スキーマを含む) は、サービス拒否攻撃に対して本質的に脆弱です。信頼できないシナリオでは受け入れないようにしてください。
  • スキーマ検証のエラー メッセージと例外により、スキーマ ファイルのコンテンツ モデルや URI パスに関する機密情報が公開される場合があります。 信頼されていない呼び出し元にこの情報を公開しないように注意してください。
  • セキュリティに関するその他の考慮事項については、「セキュリティの考慮事項」セクションを参照してください。

XmlSchemaSet は、XML スキーマ定義言語 (XSD) のスキーマを保存できるキャッシュまたはライブラリです。 XmlSchemaSet は、ファイルまたは URL からスキーマにアクセスせず、スキーマをメモリにキャッシュして、パフォーマンスを向上させます。 各スキーマは、スキーマがセットに追加されたときに指定された名前空間 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 ファイルに次の 2 つのスキーマ違反があることを示しています。

  • 最初の <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'.

入力

このサンプルは、次の 2 つの入力ファイルを使用します。

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>