XmlReaderとXML Schemaの検証

XML Schemaの本を読んでみたのですが,やっぱり予想通りめんどくさいですね.本だけ読んでてもなかなか頭に入らないので,手を動かしながら読んだほうが良さそうです.
XML文書をXML Schemaで検証するやり方ですが,C#(というか.NETライブラリ)だとXmlReader/XmlSchemaSetを使うようです.
http://msdn2.microsoft.com/ja-jp/library/as3tta56(VS.80).aspx
てっきりValidateとかいうメソッドがあるのかと思いきや,想像してたのと全然違うやりかたですね.なんだこりゃ.でも実際に動かしてみると,なかなかに味わい深いコードです.なるほどねー
とはいえ,このままだとやはり使いづらいので,勝手にリファクタリングしてみました.

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

namespace XmlValidationSample
{
  class Program
  {
    const string targetXmlFile = @"..\..\booksSchemaFail.xml";
    const string schemaFile = @"..\..\books.xsd";
    const string targetNamespace = "urn:bookstore-schema";

    static void Main(string[] args)
    {
      string errorMessages = null;
      if (!ValidatorUtil.Validate(targetXmlFile, 
                                  schemaFile, 
                                  targetNamespace, 
                                  out errorMessages))
      {
        Console.WriteLine(errorMessages);
      }
    }
  }

  public static class ValidatorUtil
  {
    public static bool Validate(string targetXmlFile, 
                                string schemaFile, 
                                string targetNamespace, 
                                out string errorMessages)
    {
      string messageBuffer = null;

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

      // Add the schema to the collection.
      sc.Add(targetNamespace, schemaFile);

      // Set the validation settings.
      XmlReaderSettings settings = new XmlReaderSettings();
      settings.ValidationType = ValidationType.Schema;
      settings.Schemas = sc;
      settings.ValidationEventHandler +=
          delegate(object sender, ValidationEventArgs e)
          {
            messageBuffer += e.Message + Environment.NewLine;
          };

      XmlReader reader = XmlReader.Create(targetXmlFile, settings);
      while (reader.Read()) ;

      return (errorMessages = messageBuffer) == null;
    }
  }
}

イベントハンドラを匿名メソッドにし,匿名メソッド内で直接Console.WriteLineするのではなく,messageBufferに書き出すようにしました.そして処理全体をValidatorUtilクラスのValidateメソッドとし,戻り値はboolで,エラーメッセージは引数のoutで返すようにしました.
一時変数(messageBuffer)を使わずに直接out引数に入れたかったのだけど,どうもそれは無理みたい.なのでちょっとだけ寄り道した感じがイマイチですが,それでも最初のサンプルよりは使いやすいんじゃないかな?