问题
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.
回答1:
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
回答2:
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
来源:https://stackoverflow.com/questions/15428265/xml-validation-and-namespaces-in-net