Я работаю с довольно сложным сторонним 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, чтобы он не работал, и похоже, что он ловит ошибки.