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.
Trying adding these settings for the
XmlValidatingReader.Settingsschema.Add()is not required in this case, as theXmlSchemaValidationFlags.ProcessInlineSchemawould process the inline schemas encountered during validation.More information