2009-11-10 7 views
9

私はXmlSerializerを使用してXml文書を逆シリアル化しています。しかし、クラスxsd.exeが生成されたクラスはxmlを読み取る機能しか提供していませんが、検証はできません。たとえば、ドキュメント内に1つのノードがない場合、期待されるように検証例外をスローするのではなく、生成されたクラスの属性フィールドがnullになります。それをどうすれば実現できますか?ありがとう!xmlserializerの検証

答えて

26

次のコードは、逆シリアル化中にスキーマに対して検証する必要があります。シリアライズ中に同様のコードを使用してスキーマに対して検証することができます。

private static Response DeserializeAndValidate(string tempFileName) 
{ 
    XmlSchemaSet schemas = new XmlSchemaSet(); 
    schemas.Add(LoadSchema()); 

    Exception firstException = null; 

    var settings = new XmlReaderSettings 
        { 
         Schemas = schemas, 
         ValidationType = ValidationType.Schema, 
         ValidationFlags = 
          XmlSchemaValidationFlags.ProcessIdentityConstraints | 
          XmlSchemaValidationFlags.ReportValidationWarnings 
        }; 
    settings.ValidationEventHandler += 
     delegate(object sender, ValidationEventArgs args) 
     { 
      if (args.Severity == XmlSeverityType.Warning) 
      { 
       Console.WriteLine(args.Message); 
      } 
      else 
      { 
       if (firstException == null) 
       { 
        firstException = args.Exception; 
       } 

       Console.WriteLine(args.Exception.ToString()); 
      } 
     }; 

    Response result; 
    using (var input = new StreamReader(tempFileName)) 
    { 
     using (XmlReader reader = XmlReader.Create(input, settings)) 
     { 
      XmlSerializer ser = new XmlSerializer(typeof (Response)); 
      result = (Response) ser.Deserialize(reader); 
     } 
    } 

    if (firstException != null) 
    { 
     throw firstException; 
    } 

    return result; 
} 
+2

この解決策をお寄せいただきありがとうございます。これにより、XmlReaderを介して検証することによってデシリアライズと並行して検証が行われるため、より良いアプローチです。 – el2iot2

4

次のコードは、スキーマファイルに対してXMLを手動で読み込んで検証し、resulting errors and/or warningsを処理できるようにします。

//Read in the schema document 
using (XmlReader schemaReader = XmlReader.Create("schema.xsd")) 
{ 
    XmlSchemaSet schemaSet = new XmlSchemaSet(); 

    //add the schema to the schema set 
    schemaSet.Add(XmlSchema.Read(schemaReader, 
    new ValidationEventHandler(
     delegate(Object sender, ValidationEventArgs e) 
     { 
     }  
    ))); 

    //Load and validate against the programmatic schema set 
    XmlDocument xmlDocument = new XmlDocument(); 
    xmlDocument.Schemas = schemaSet; 
    xmlDocument.Load("something.xml"); 

    xmlDocument.Validate(new ValidationEventHandler(
     delegate(Object sender, ValidationEventArgs e) 
     { 
      //Report or respond to the error/warning 
     } 
    )); 
} 

は今、明らかに、あなたはこれを自動的に行うためにXsd.exeではにより生成されたクラスを持たせたいとロード中に(上記のアプローチは、XMLファイルの第2のハンドリングを必要とする)が、前負荷の検証が可能になります不正な形式の入力ファイルをプログラムで検出することができます。

+0

@ジョンサンダース - 私はクラスの生成コードは、その動作いつでもすぐに変更する可能性がある、とMSDNのサイトがXsd.exeではには、関連するオプションを示していないことを疑っていたので、私はそれを示唆するのが妥当だと思います回避策... – el2iot2

+1

質問のテキストで、OPは無効な入力xmlに対して例外がスローされることを希望していると表現しています。このアプローチはそれを達成します。私はこれが実行できる唯一の方法であると主張していない、あるいはそれが最善の方法であるということさえもありません。しかし、私は過去にXML文書の一般的な検証に使用していたアプローチ(私の頭の上から外れている)に対応していました。 – el2iot2