Самый эффективный способ проверки XML на XSD - PullRequest
7 голосов
/ 08 сентября 2010

Я получаю строковую переменную с XML-файлом и XSD-файл. Я должен проверить XML в строке по отношению к файлу XSD и знать, что существует несколько способов (XmlDocument, XmlReader, ...?).

После проверки мне просто нужно сохранить XML, поэтому он мне не нужен в XDocument или XmlDocument.

Какой способ пойти, если я хочу самую быструю производительность?

Ответы [ 4 ]

10 голосов
/ 08 сентября 2010

Другие уже упоминали класс XmlReader для выполнения проверки, и я не буду подробно останавливаться на этом.

Ваш вопрос не определяет много контекста. Будете ли вы выполнять эту проверку повторно для нескольких XML-документов или только один раз? Я читаю сценарий, в котором вы просто проверяете множество XML-документов (из сторонней системы?) И сохраняете их для будущего использования.

Мой вклад в поиск производительности будет заключаться в использовании скомпилированного XmlSchemaSet, который будет потокобезопасным, поэтому несколько потоков могут использовать его без необходимости повторного анализа документа xsd.

var xmlSchema = XmlSchema.Read(stream, null);
var xmlSchemaSet = new XmlSchemaSet();
xmlSchemaSet.Add(xmlSchema);
xmlSchemaSet.Compile();

CachedSchemas.Add(name, xmlSchemaSet);
3 голосов
/ 08 сентября 2010

Я бы пошел за XmlReader с XmlReaderSettings, потому что не нужно загружать полный XML в памяти. Это будет более эффективно для больших файлов XML.

2 голосов
/ 08 сентября 2010

Я думаю, что самый быстрый способ - использовать XmlReader, который проверяет документ во время его чтения.Это позволяет проверить документ за один проход: http://msdn.microsoft.com/en-us/library/hdf992b8.aspx

0 голосов
/ 08 сентября 2010

Используйте XmlReader, настроенный для выполнения проверки, с источником TextReader.

Вы можете вручную указать XSD, который XmlReader будет использовать, если вы не хотите полагаться на объявления во входном документе (со свойством XmlReaderSettings.Schemas)

Начало (просто предполагается, что объявления экземпляра XSD во входном документе) будет:

var settings = new XmlReaderSettings {
   ConformanceLevel = ConformanceLevel.Document,
   ValidationType = ValidationType.Schema,
   ValidationFlags = XmlSchemaValidationFlags.ProcessSchemaLocation |
                     XmlSchemaValidationFlags.ProcessInlineSchema,
};

int warnings = 0;
int errors = 0;
settings.ValidationEventHandler += (obj, ea) => {
   if (args.Severity == XmlSeverityType.Warning) {
      ++warnings;
   } else {
      ++errors;
   }
};

XmlReader xvr = XmlReader.Create(new StringReader(inputDocInString), settings);

try {
   while (xvr.Read()) {
      // do nothing
   }

   if (0 != errors) {
      Console.WriteLine("\nFailed to load XML, {0} error(s) and {1} warning(s).", errors, warnings);
   } else if (0 != warnings) {
      Console.WriteLine("\nLoaded XML with {0} warning(s).", warnings);
   } else {
      System.Console.WriteLine("Loaded XML OK");
   }

   Console.WriteLine("\nSchemas loaded durring validation:");
   ListSchemas(xvr.Schemas, 1);

} catch (System.Xml.Schema.XmlSchemaException e) {
   System.Console.Error.WriteLine("Failed to read XML: {0}", e.Message);
} catch (System.Xml.XmlException e) {
   System.Console.Error.WriteLine("XML Error: {0}", e.Message);
} catch (System.IO.IOException e) {
   System.Console.Error.WriteLine("IO error: {0}", e.Message);
}
...