2009-11-10 4 views
9

Я использую XmlSerializer для десериализации Xml. Но я обнаружил, что генерируемый класс xsd.exe предлагает только возможность читать xml, но без проверки. Например, если в документе отсутствует один узел, поле атрибута сгенерированного класса будет равно 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), а Validate предварительной нагрузки позволит вы программно обнаруживаете искаженный входной файл.

+0

@John Сондерс - я сомневаюсь, что код поколения класса, скорее всего, в ближайшее время изменить его действие в любое время, а также на сайте MSDN не показывает соответствующие параметры для Xsd.exe, так что я думаю, что это разумно, чтобы предложить обходной путь ... – el2iot2

+1

В тексте вопроса OP выражает, что он хочет, чтобы исключение было выбрано для недопустимого ввода xml. Этот подход делает это. Я не утверждаю, что это единственный способ сделать это, или даже это лучший способ. Но я отвечал подходом (с моей головы), который я использовал в прошлом, чтобы в целом проверить XML-документы. – el2iot2

Смежные вопросы