2011-10-22 15 views
6

を検証するときにこれがこの質問C# Get schema information when validating xmlはXDocument

に似てスキーマ情報をキャプチャしかし、私は、LINQの目的のためにXDocumentで働いています。

私はCSVファイルのセットを読み込み/解析してXMLに変換してから、XSDスキーマに対してXMLを検証しています。

要素値に関連する特定のエラーをキャプチャし、よりユーザーフレンドリーなメッセージを生成し、ユーザーに戻して入力データを修正できるようにしたいと考えています。出力データに含める項目の1つに、スキーマ情報(数値型の許容値の範囲など)があります。

私の現在のアプローチ(私は変更が可能です)では、スキーマ情報を除いて必要なものをすべて取得できます。

Validationイベントハンドラの引数ValidationEventArgsSourceSchemaObjectにアクセスしようとしましたが、常にnullです。私はまた、XElementのGetSchemaInfoを試しましたが、それもnullであるようです。

RegExを使用して、キャプチャする特定の検証エラーを特定し、検証イベントハンドラの送信者引数を使用してXElementからデータを取得しています。ここだ

private List<String> this.validationWarnings; 
private XDocument xDoc; 
private XmlSchemaSet schemas = new XmlSchemaSet(); 

public List<String> Validate() 
{ 
    this.validationWarnings = new List<String>(); 

    // the schema is read elsewhere and added to the schema set 
    this.xDoc.Validate(this.schemas, new ValidationEventHandler(ValidationCallBack), true); 

    return validationWarnings 
} 

そして:私はXDocumentにスキーマを変換すると、私はLINQを経由して必要なものをつかむと思ったが、良いオプションがあるべきように思わまし

ここに私の現在の検証方法です私のコールバックメソッド:

private void ValidationCallBack(object sender, ValidationEventArgs args) 
{   
    var element = sender as XElement; 

    if (element != null) 
    { 

     // this is a just a placeholder method where I will be able to extract the 
     // schema information and put together a user friendly message for specific 
     // validation errors  
     var message = FieldValidationMessage(element, args); 

     // if message is null, then the error is not one one I wish to capture for 
     // the user and is related to an invalid XML structure (such as missing 
     // elements or incorrect order). Therefore throw an exception 
     if (message == null) 
      throw new InvalidXmlFileStructureException(args.Message, args.Exception); 
     else 
      validationWarnings.Add(message); 

    } 
} 

私のコールバックメソッドでvar message = FieldValidationMessage(element, args);行はプレースホルダで、まだこの方法の意図は3つの事を行うことですが存在しません:

  1. args.Messageに正規表現を使用して、特定の検証エラーを識別し(これはすでに私が使用する予定のパターンをテストしている、作品)

  2. グラブは、エラーの原因となっている特定のXElementに関連XDocumentから属性値を(元のCSVの行番号や列番号など)

  3. スキーマ情報がある場合はそれを取得して、フィールドタイプと制限を出力メッセージに追加できるようにします。

答えて

6

今後この問題を読む人にとっては、私が最初に提案した方法とは若干異なる方法でも問題を解決することができました。

最初の問題は、ValidationEventArgsとXElementのGetSchemaInfo拡張メソッドの両方のSchemaInfoがnullだったことです。私は元々リンクした質問と同じ方法でそれを解決しました....

List<XElement> errorElements = new List<XElement>(); 

serializedObject.Validate((sender, args) => 
{ 
    var exception = (args.Exception as XmlSchemaValidationException); 

    if (exception != null) 
    { 
     var element = (exception.SourceObject as XElement); 

     if (element != null) 
      errorElements.Add(element); 
    } 

}); 

foreach (var element in errorElements) 
{ 
    var si = element.GetSchemaInfo(); 

    // do something with SchemaInfo 
} 

スキーマ情報を検証コールバック後までのXObjectに追加されていないように思われるので、あなたが検証コールバックの途中でそれにアクセスしようとすると、それはnullになりますが、あなたがキャプチャした場合Validateメソッドが完了した後にアクセスすると、nullになりません。

しかし、これによって別の問題が発生しました。 SchemaInfoオブジェクトモデルは十分に文書化されておらず、必要なものを見つけるために解析するのに問題がありました。

私が元の質問をした後、これはquestionでした。受け入れられた答えは、実際に大きなblogポストへのリンクで、SchemaInfoオブジェクトモデルを分解します。私の目的に合うようにコードを洗練するために少し手間がかかりましたが、どのXmlReader要素(これをXObjectで動作するように変更できたか)のSchemaInfoを取得する方法を説明するのは良い仕事です。