6

我想要做的是针对 XSD 验证 XML。这一切都非常简单,但是我遇到了没有命名空间的 XML 的问题。C# 仅在命名空间与 XSD 的目标命名空间匹配时才验证 xml。这似乎是正确的,但是没有命名空间的 XML 或与 SchemaSet 不同的 XML 应该给出异常。是否有实现此目的的属性或设置?还是我必须通过读取 xml 的 xmlns 属性来手动获取命名空间?

清除示例:

代码:

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>

有效的 XML:

<test xmlns="http://example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">112.1</test>

无效的 XML,这将无法验证:

<hello xmlns="http://example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">112.1</hello>

错误:The 'http://example.com:hello' element is not declared

无效的 XML,但会验证,因为命名空间不存在:

<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">112.1</hello>

我怎样才能解决这个问题?

非常感谢任何帮助。

4

2 回答 2

4

xml 中的无效命名空间没有触发XmlSchemaValidationException, 的原因是,它只是一个警告。

因此,我们必须更改代码,以便同时报告警告。

第一:设置Validationflags属性XmlReaderSettings

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

PS:通过设置验证标志,确保你设置了所有需要的标志,否则一些验证检查将被跳过。我正在使用ProcessIdentityConstraints,所以我的身份约束(xs:key,xs:keyref,...)也得到了验证。更多信息请访问http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschemavalidationflags.aspx

Next:告诉验证器在报告警告时该怎么做。创建一个Validator事件,当警告或错误发生时触发

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



    }

最后:设置要用于验证的验证器事件处理程序

settings.ValidationEventHandler += new ValidationEventHandler(SchemaValidatorHandler);

就是这样

于 2013-03-29T11:02:59.533 回答
1

我可以找到XmlDocument.Validate()
http://msdn.microsoft.com/en-us/library/ms162371.aspx的方法

我相信如果 XmlDocument 中有错误并且命名空间不匹配它会抛出警告,它会抛出异常。您可以阅读有关 XmlValidation 和错误类型的更多信息。 http://msdn.microsoft.com/en-us/library/aa310912%28v=vs.71%29.aspx

粘贴在 msdn 警告的部分摘录下方
如果调用 ValidationEventHandler 并传递一个等于 XmlSeverityType.Warning 的 ValidationEventArgs.Severity,则继续处理文档。不会引发异常,并且继续处理模式文档。错误 如果调用 ValidationEventHandler 并传递一个等于 XmlSeverityType.Error 的 ValidationEventArgs.Severity,则继续处理文档并丢弃无效数据。抛出异常并且模式文档的处理停止。
希望这可以帮助

于 2013-03-15T10:33:58.130 回答