2

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.

Paul Mrozowski
  • 6,604
  • 9
  • 34
  • 47

1 Answers1

2

Trying adding these settings for the XmlValidatingReader.Settings

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

validating.Settings = settings;

schema.Add() is not required in this case, as the XmlSchemaValidationFlags.ProcessInlineSchema would process the inline schemas encountered during validation.


More information

Devendra D. Chavan
  • 8,871
  • 4
  • 31
  • 35
  • That code didn't work (you can't assign settings that way - it's a read-only property) but I modified the above code and got it working. – Paul Mrozowski Jun 03 '11 at 13:44
  • 1
    Hmm...apparently I didn't have my Validation event hooked up properly. As soon as I re-connected it, I get the same exact errors being reported. Taking out the Schema.Add call had no effect - same error messages. – Paul Mrozowski Jun 03 '11 at 13:53
  • Take a look at a similar question: [Validating an XML against referenced XSD in C#](http://stackoverflow.com/questions/751511/validating-an-xml-against-referenced-xsd-in-c) – Devendra D. Chavan Jun 03 '11 at 14:14