Как исправить ошибку «Не удалось найти схему ...» при проверке XML на XSD? - PullRequest
2 голосов
/ 03 июня 2011

Я работаю с довольно сложным сторонним XSD-форматом - XSD относятся к типам в другом XSD, который относится к типам в еще одном XSD. Мне нужно иметь возможность проверять XML на соответствие этому формату. Мне удалось проверить это с помощью XML Spy, но теперь нам нужен более автоматизированный подход.

Я загружаю XSD, используя немного более сложную версию этого кода, но они эквивалентны (если я не сделал опечаток):

string xmlFile = @"C:\tmp\testxml\Valid.xml";
string xsdFile = @"C:\tmp\testxml\DRO.xsd";

var schema = new XmlSchemaCollection();
var reader = new FileStream(xmlFile, FileMode.Open);
var validating = new XmlValidatingReader(reader, XmlNodeType.Element, null);

// Removed 3 other XSDs to simplify a bit, but are included in the real code
schema.Add("http://www.test.com/PTS/Formdom", @"C:\tmp\textxml\Formdom.xsd");
schema.Add("http://www.test.com/PTS/DRO", @"C:\tmp\textxml\DRO.xsd");

validating.ValidationType = ValidationType.Schema;
validating.ValidationEventHandler += validating_ValidationEventHandler;

while (validating.Read()) {} 

// More code removed

XML-файл выглядит следующим образом - я обрезал его до той части, где возникает первая ошибка:

<?xml version="1.0" encoding="UTF-8" ?>
 <dro:DRO 
xmlns:dro="http://www.test.com/PTS/DRO" 
xmlns:for="http://www.test.com/PTS/Formdom" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.test.com/PTS/DRO" >

    <dro:HeaderSection>
       <dro:VersionNumber>1.2</dor:VersionNumber>
    </dro:HeaderSection>
 </dro:DRO>

DRO.XSD выглядит так (опять же сильно обрезано):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.test.com/PTS/DRO" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:FF="http://www.test.com/PTS/FormFields" 
xmlns:CD="http://www.test.com/PTS/Formdom" 
xmlns:CF="http://www.test.com/PTS/CommonFields" 
targetNamespace="http://www.test.com/PTS/DRO" 
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:import namespace="http://www.test.com/PTS/FormFields" schemaLocation="FormFields.xsd"/>
<xs:import namespace="http://www.test.com/PTS/Formdom" schemaLocation="FormDom.xsd"/>
<xs:import namespace="http://www.test.com/PTS/CommonFields" schemaLocation="CommonFields.xsd"/>
<xs:element name="DRO">
<xs:complexType>
   <xs:sequence>
     <xs:element name="HeaderSection" type="HeaderSection"/>
       </xs:sequence>
    </xs:complexType>

Я предполагаю, что ошибка заключается в том, как сконфигурированы элементы xmlns и targetNamespace, и я убедился, что они точно совпадают (и даже случай одинаков). Я также убедился, что при добавлении схемы в мой C # целевое пространство имен совпадает. В приведенном выше коде я вручную задаю имя, но в реальном коде извлекаю targetNamespace из XSD и использую его.

Когда я запускаю код, я могу успешно добавить все XSD, но как только он начинает читать XML-файл, происходит сбой с этими ошибками:

Не удалось найти информацию о схеме для элемента «http://www.test.com/PTS/DRO:DRO' Не удалось найти информацию о схеме для элемента «http://www.test.com/PTS/DRO:HeaderSection'

(плюс куча других подобных ошибок)

Я просто не вижу, что мне нужно сделать, чтобы сделать эту работу. Есть идеи?

РЕДАКТИРОВАТЬ: я снова просмотрел этот код и понял, что на самом деле я ничего не делал со своими схемами. Я добавлял их в коллекцию XmlSchemaCollection, но я ни к чему не привязывал. Я изменил код для использования класса XmlReaderSettings (), а затем добавил схемы в его коллекцию схем:

var settings = new XmlReaderSettings();
// Code removed
settings.Schema.Add("http://www.test.com/PTS/Formdom", @"C:\tmp\textxml\Formdom.xsd");
// Code removed
var validating = XmlReader.Create(reader, settings);

Похоже, что это действительно работает (да!). Я внес небольшие изменения в документ XML, чтобы он не работал, и похоже, что он ловит ошибки.

1 Ответ

2 голосов
/ 03 июня 2011

Попытка добавить эти настройки для XmlValidatingReader.Settings

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;

validating.Settings = settings;

schema.Add() в этом случае не требуется, поскольку XmlSchemaValidationFlags.ProcessInlineSchema будет обрабатывать встроенные схемы, обнаруженные во время проверки.


Дополнительная информация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...