Я хочу проверить (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.
.
Так что, очевидно, мне нужно либо добавить это явно, либо нет, в зависимости от того, способна ли машина загрузить его из Интернета (или даже, возможно, ранее могла его загрузить, и где-то кешируется) ).
1116 Итак, «проклято, если я сделаю, и проклято, если я не сделаю». Должен ли я попробовать это одним способом, поймать исключение, а затем попробовать другим способом? Или есть более элегантное решение?
Мы не можем видеть ваш код, но Во многих реализациях это обрабатывается путем перенаправления запроса .xsd на локальную копию с помощью преобразователя каталога. Для этого можно использовать свойство XmlReaderSettings.XmlResolver . См. XMLCatalog.net для реализации лицензированной Apache, которую вы можете использовать.
Побочным эффектом этого является то, что вы можете хранить все схемы в кэше локально. Это особенно важно, поскольку W3C будет блокировать чрезмерное количество операций чтения со своего сайта, и случайным образом ваш код (или, что еще хуже, код вашего клиента) начнет давать сбой.