Наиболее эффективный способ проверки XML на XSD
Я получаю строковую переменную с XML и имею XSD-файл. Я должен проверить XML в строке против xsd-файла и знать, что есть несколько способов (XmlDocument, XmlReader,... ?).
после проверки мне просто нужно сохранить XML, поэтому он мне не нужен в XDocument или XmlDocument.
Каков путь, если я хочу самую быструю производительность?
4 ответов
другие уже упоминали о XmlReader
класс для выполнения проверки, и я не буду вдаваться в подробности.
Ваш вопрос не уточняет, сколько контекст. Вы будете делать эту проверку повторно для нескольких xml-документов или только один раз? Я читаю сценарий, в котором вы просто проверяете много xml-документов (из сторонней системы?) и хранить их для будущего использования.
мой вклад в охоту за производительностью будет заключаться в использовании скомпилированного XmlSchemaSet
который был бы потокобезопасным, поэтому несколько потоков могут повторно использовать его без необходимости снова анализировать документ xsd.
var xmlSchema = XmlSchema.Read(stream, null);
var xmlSchemaSet = new XmlSchemaSet();
xmlSchemaSet.Add(xmlSchema);
xmlSchemaSet.Compile();
CachedSchemas.Add(name, xmlSchemaSet);
Я бы пошел на XmlReader с XmlReaderSettings, потому что не нужно загружать полный XML в память. Это будет более эффективно для больших XML-файлов.
Я думаю, что самый быстрый способ-использовать XmlReader, который проверяет документ по мере его чтения. Это позволяет проверить документ только за один проход:http://msdn.microsoft.com/en-us/library/hdf992b8.aspx
использовать 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);
}