I am working with a fairly complex third-party XSD format - XSDs refer to types in another XSD which refers to types in yet another XSD. I need to be able to validate XML against this format. I've been able to get this to validate using XML Spy but now we need a more automated approach.
I am loading the XSDs using a slightly more complex version of this code, but they are equivalent (as long as I haven't made any typos):
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
The XML file looks like this - I've trimmed it WAY down to just the section where the first error occurs:
<?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>
The DRO.XSD looks like this (again, heavily trimmed down):
<?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>
I'm assuming the error is located in how the xmlns and targetNamespace stuff is configured and I've made sure that they match exactly (and that even the case is the same). I also made sure that when I add the schema in my C# the target namespace matches. In the code I show above I manually set the name but in the real code I extract the targetNamespace from the XSD and use that.
When I run the code I can successfully add all of the XSDs, but as soon as it starts reading the XML file it fails with these errors:
Could not find schema information for the element 'http://www.test.com/PTS/DRO:DRO' Could not find schema information for the element 'http://www.test.com/PTS/DRO:HeaderSection'
(plus a ton of other similar errors)
I'm just not seeing what I need to do to make this work. Any ideas?
EDIT: I've gone back through this code again and realized I wasn't actually doing anything with my schemas. I was adding them to a XmlSchemaCollection but I wasn't attaching that to anything. I modified the code to use the XmlReaderSettings() class, then added the schemas to it's Schema collection:
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);
This looks like it's actually working (yeah!). I've made small changes to the XML doc to get it to fail and it looks like it's catching the errors.