2009-11-10 13 views
9

Ich verwende XmlSerializer, um Xml achiales zu deserialisieren. Aber ich fand die Klasse xsd.exe generiert bietet nur die Fähigkeit, die XML zu lesen, aber keine Validierung. Wenn beispielsweise ein Knoten in einem Dokument fehlt, ist das Attributfeld der generierten Klasse null und löst nicht wie erwartet eine Validierungsausnahme aus. Wie kann ich das erreichen? Vielen Dank!xmlserializer Validierung

Antwort

26

Der folgende Code sollte beim Deserialisieren gegen ein Schema validiert werden. Ein ähnlicher Code kann verwendet werden, um beim Serialisieren gegen ein Schema zu validieren.

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

Danke, dass Sie diese Lösung teilen. Da die Validierung in Übereinstimmung mit der Deserialisierung durch Validierung über den XmlReader erfolgt, ist dies ein besserer Ansatz. – el2iot2

4

Der folgende Code lädt und validiert Ihre XML manuell mit einer Schemadatei programmgesteuert, so dass Sie mit jeder resulting errors and/or warnings umgehen können.

//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 
     } 
    )); 
} 

Jetzt offensichtlich wünschen Sie die Klassen von xsd.exe erzeugt haben, dies automatisch zu tun und beim Laden (der obige Ansatz würde einen zweiten Umgang mit der XML-Datei benötigen), aber eine Vorbelastung Validate erlauben würde, Sie können eine fehlerhafte Eingabedatei programmgesteuert erkennen.

+0

@ John Saunders - Ich bin zu zweifeln, dass die Klasse Generation Code wahrscheinlich ist sein Betrieb in absehbarer Zeit zu ändern, und die MSDN-Site zeigt keine relevanten Optionen für xsd.exe, so dass ich denke, dass es sinnvoll ist ein vorschlagen Problemumgehung ... – el2iot2

+1

In dem Fragetext drückt das OP aus, dass er möchte, dass eine Ausnahme für ein ungültiges Eingabexml ausgelöst wird. Mit diesem Ansatz wird das erreicht. Ich behaupte nicht, dass dies die einzige Möglichkeit ist, oder sogar, dass es der beste Weg ist. Aber ich reagierte mit einem Ansatz (von Kopf bis Fuß), den ich in der Vergangenheit verwendet hatte, um XML-Dokumente allgemein zu validieren. – el2iot2

Verwandte Themen