Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML validation and namespaces in .NET

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.

like image 293
JeanD Avatar asked Mar 15 '13 09:03

JeanD


People also ask

Which are the namespaces in .NET used for XML?

XML namespaces associate element and attribute names in an XML document with custom and predefined URIs. To create these associations, you define prefixes for namespace URIs, and use those prefixes to qualify element and attribute names in XML data.

What is XML validation in asp net?

XML validation is the process of checking a document written in XML (eXtensible Markup Language) to confirm that it is both well-formed and also "valid" in that it follows a defined structure. A well-formed document follows the basic syntactic rules of XML, which are the same for all XML documents.

How XML is used for validation?

XML validation is the process of determining whether the structure, content, and data types of an XML document are valid. XML validation also strips off ignorable whitespace in the XML document.

What is Namespace in XML schema?

What Is an XML Namespace? An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.


2 Answers

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

like image 96
JeanD Avatar answered Oct 19 '22 19:10

JeanD


I can find there is a method for XmlDocument.Validate()
http://msdn.microsoft.com/en-us/library/ms162371.aspx

I believe it would throw an exception if there is an error in the XmlDocument and for the namespace not matching it would throw warning. You can read more about XmlValidation and error types. http://msdn.microsoft.com/en-us/library/aa310912%28v=vs.71%29.aspx

Pasted below some excerpt from msdn
Warning If the ValidationEventHandler is called and is passed a ValidationEventArgs.Severity that is equal to XmlSeverityType.Warning, processing of the document continues. No exception is thrown and processing of the schema document continues. Error If the ValidationEventHandler is called and is passed a ValidationEventArgs.Severity that is equal to XmlSeverityType.Error, processing of the document continues and invalid data is discarded. An exception is thrown and processing of the schema document stops.
Hope this helps

like image 1
Rameez Ahmed Sayad Avatar answered Oct 19 '22 21:10

Rameez Ahmed Sayad