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.
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.
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.
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 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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With