XML validation and namespaces in .NET

c#, xsd-validation

Solution

The reason why invalid namespaces in the xml aren't triggering the `XmlSchemaValidationException` , is, because it is just a warning.

So, we have to change the code so warnings are also reported.

First: Set the `Validationflags` property in the `XmlReaderSettings`

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings;

PS:By setting validation flags, make sure you set all the flags needed, otherwise some validationchecks will be skipped. I'm using `ProcessIdentityConstraints`, so my identity-constraints(xs:key, xs:keyref,...) are also validated. More info at http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschemavalidationflags.aspx.

Next: tell the validator what to do when a warning is reported. Create a Validator event, that will be triggered when a warning or error occurs

private static void SchemaValidatorHandler(object sender, ValidationEventArgs e)
    {
        if (e.Severity == XmlSeverityType.Warning || e.Severity == XmlSeverityType.Error)
        {
            //Handle your exception
        }



    }

Last: Set the validator event handler you want to use for your validation

settings.ValidationEventHandler += new ValidationEventHandler(SchemaValidatorHandler);

That's it

Problem

What I'm trying to do is to validate XML against an XSD. This is all pretty straightforward, but I'm having a problem with XML's without a namespace. C# only validates the xml if the namespace matches the targetnamespace of the XSD. This seems right, but an XML with no namespace or a different one then the SchemaSet should give an exception. Is there a property or a setting to achieve this? Or do I have to get the namespace manually by reading the xmlns attribute of the xml? An example to clearify: Code: ``` XmlReaderSettings settings = new XmlReaderSettings(); settings.Schemas.Add("http://example.com", @"test.xsd"); settings.Schemas.Add("http://example.com/v2", @"test2.xsd"); settings.ValidationType = ValidationType.Schema; XmlReader r = XmlReader.Create(@"test.xml", settings); XmlReader r = XmlReader.Create(new StringReader(xml), settings); XmlDocument doc = new XmlDocument(); try { doc.Load(r); } catch (XmlSchemaValidationException ex) { Console.WriteLine(ex.Message); } ``` XSD: ``` <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com" targetNamespace="http://example.com" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="test"> <xs:annotation> <xs:documentation>Comment describing your root element</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]+\.+[0-9]+" /> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema> ``` Valid XML: ``` <test xmlns="http://example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">112.1</test> ``` Invalid XML, this will not validate: ``` <hello xmlns="http://example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">112.1</hello> ``` Error: `The 'http://example.com:hello' element is not declared`. Invalid XML, but will validate, because namespace is not present: ``` <hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">112.1</hello> ``` How can I fix this? Any help much appreciated.

Original source