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引数に入れたかったのだけど,どうもそれは無理みたい.なのでちょっとだけ寄り道した感じがイマイチですが,それでも最初のサンプルよりは使いやすいんじゃないかな?