XML validation and namespaces in .NET

时光总嘲笑我的痴心妄想 提交于 2020-12-05 08:51:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!