Использование .NET для проверки XML в отношении схемы

Я хочу проверить (true или false), соответствует ли произвольный XML файл данной схеме.

Для того, что стоит, схема представляет собой WordML-схему Word 2003, которую Microsoft определяет с помощью списка из примерно 7 *.xsd файлов.

Один из этих файлов также включает в себя файл W3C xml.xsd, включая следующую инструкцию:

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import>

Для проверки правильности использую следующий код .NET:

   public static void validate(string filename)
    {
       XmlReaderSettings settings = new XmlReaderSettings();
       settings.Schemas.Add(
           "http://schemas.microsoft.com/office/word/2003/wordml",
           //to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe" 
           @"C:\Program Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd"
           );
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler);
        XmlReader xmlReader = XmlReader.Create(filename, settings);
        while (xmlReader.Read()) { }
   }

Моя проблема в том, что если я запустил этот код на машине, которая не подключена к Интернету, тогда я получаю ошибку XmlSchemaValidationException, что он не может найти xml.xsd.

Чтобы исправить это, я загрузил копию xml.xsd и добавлю ее явно с помощью метода settings.Schemas.Add: проверка правильности работы корректно работает, когда машина не подключена к Интернету.

Однако, когда машина подключена к Интернету, теперь я получаю сообщение об ошибке The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared..

Поэтому, по-видимому, мне нужно либо добавить его явно, либо я не могу, в зависимости от того, сможет ли компьютер тихо загрузить его из Интернета (или даже, возможно, ранее мог его загрузить, и он кэшировал где-то).

Итак, "черт возьми, если я и проклят, если не буду". Нужно ли мне попробовать это в одну сторону, поймать исключение, а затем попробовать другое? Или есть более элегантное решение?

Ответ 1

Мы не можем видеть ваш код, но. Во многих реализациях это обрабатывается путем перенаправления запроса .xsd на локальную копию с помощью распознавателя каталога. Существует свойство XmlReaderSettings.XmlResolver, которое можно использовать для этого. См. XMLCatalog.net для реализации, лицензированной Apache, которую вы можете использовать.

Побочным эффектом является то, что вы можете хранить все схемы в кэше локально. Это особенно важно, так как W3C будет блокировать чрезмерные чтения на своем сайте и случайным образом ваш код (или, что еще хуже, ваш код клиента) начнет сбой.