XSD による XML の検証

XML で何らかのデータの受け渡しをするわけですが、その XML 自体が正しいデータを運んでいることをチェックする必要があります。

これは XSD で簡単に実現できます。

この資料では XSD (XML Schema Definition. XML スキーマ定義) の簡単なクラッシュコースを含み、 それに従った XML であることを検証するプログラムをみてみましょう。

XSD の書き方・仕組み

XML は何らかの形で使ったことがある人は多いと思いますので、まずは XML からスタートしましょう。

次のような XML があったとします。

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="urn:bookstore-schema">
  <book genre="novel">
    <title>The 7 Habits</title>
    <author>
      <first-name>Keith</first-name>
      <last-name>Oyama</last-name>
    </author>
    <price>10.00</price>
  </book>
</bookstore>

bookstore というルート要素の中に book 要素があります。そしてその book 要素はタイトル (title)、著者 (author)、価格 (price) の要素をもつ。 そして著者要素は姓と名(last-name と first-name)に分かれるという構成です。

ちなみに、book 要素には ジャンル (genre) という属性が付いてたりします。

こんな XML スキーマを XSD 文書ではどのように定義するのでしょうか。

XSD は次の通り。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
  targetNamespace="urn:bookstore-schema"
  xmlns="urn:bookstore-schema"
  elementFormDefault="qualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="bookstore" type="bookstoreType"/>
  <xs:complexType name="bookstoreType">
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="book" type="bookType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="bookType">
    <xs:sequence>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="author" type="authorType"/>
      <xs:element name="price" type="xs:decimal" minOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="genre" type="xs:string"/>
  </xs:complexType>

  <xs:complexType name="authorType">
    <xs:sequence>
      <xs:element name="first-name" type="xs:string"/>
      <xs:element name="last-name" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

xs: という接頭辞は xmlns:xs="http://www.w3.org/2001/XMLSchema" と書いてあるので、ここでは XML スキーマのプリミティブな型を表しています。

なので、ここでは xs:string という風に xs: で始まっていたら「あ、"普通の" string だな」などと考えて OK です。

xs:element で "要素" を定義しているわけですが、注意してみていくと、ひとつめは "bookstore" という名前の要素を定義していることがわかります。 そしてその bookstore の型 (type) は bookstoreType であると書いてあります。

すると、次の行に xs:complexType とあり、それの名前が bookstoreType です。

compleType は C 言語の構造体のようなものをイメージすればよいでしょう。複数の要素を纏め上げた型を定義するために使われます。

従って、ここをみると bookstoreType という型は bookType 型の book 要素のシーケンスであることがわかります。

という風に、順番に見ていくとこの XSD の構造が見えてくると思います。

ポイントに色づけするとこんな風になるでしょうか。

XSD

XSD を用いた XML の検証

XML のライブラリを使うとある XML が特定の XSD での定義に従っていることを簡単にチェックできるというわけです。

上記 XML、XSD を xml1.xml、schema1.xsd として、次のコードで検証できます。

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

namespace XmlValidate1
{
  class Program
  {
    public static void Main()
    {
      XmlSchema schema = null;
      XmlSchemaSet schemaSet = new XmlSchemaSet();
      schemaSet.Add("urn:bookstore-schema", @"C:\Temp\schema1.xsd");
    
      foreach (XmlSchema s in schemaSet.Schemas())
      {
        schema = s;
      }

      XmlDocument xdoc = new XmlDocument();
      xdoc.Schemas.Add(schema);
      xdoc.Load(@"C:\Temp\xml1.xml");
      xdoc.Validate(ValidationCallBack);
    }

    private static void ValidationCallBack(object sender, 
      ValidationEventArgs args)
    {
      if (args.Severity == XmlSeverityType.Error)
      {
        Console.WriteLine("Error: " + args.Message);
      }
    }
  }
}

例えば上記 xml から price 要素を削除して、実行すると次のようなエラーが記録されます。

Error: The element 'book' in namespace 'urn:bookstore-schema' 
has incomplete content. List of possible elements expected: 
'price' in namespace 'urn:bookstore-schema'.

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 C# 入門