疾风萧萧

See, this isn't the finish line.The future is the finish line......
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在.Net代码中验证XML文档

Posted on 2005-12-10 16:29  疾风  阅读(1063)  评论(0编辑  收藏  举报

    在验证某个xml文档是否符合某个格式时,你还在使用用代码一个节点一个节点、一个属性一个属性读取、判断的方法么?呵呵,那可就落后了,.Net Framework提供了一些好用的基础设施来帮助我们来完成这项工作。

    我们先把这些基础设施给列一下(其介绍是从MSDN中Copy下来的,我就懒得翻译啦):

    1. XmlReader

    provides forward-only, read-only access to a stream of XML data. The XmlReader class conforms to the W3C Extensible Markup Language (XML) 1.0 and the Namespaces in XML recommendations.
    Although the Microsoft .NET Framework includes concrete implementations of the XmlReader class, such as the XmlTextReader, XmlNodeReader, and the XmlValidatingReader classes, in the 2.0 release the recommended practice is to create XmlReader instances using the Create method. For more information, see Creating XML Readers.

    2. XmlReaderSettings
    Specifies a set of features to support on the XmlReader object created by the Create method.

    使用XmlReaderSettings需要注意的地方:

    1) The ProcessInlineSchema and ProcessSchemaLocation validation flags of an XmlReaderSettings object are not set by default. When these flags are set, the XmlResolver of the XmlReaderSettings object is used to resolve schema locations encountered in the instance document in the XmlReader. If the XmlResolver object is a null reference (Nothing in Visual Basic), schema locations are not resolved even if the ProcessInlineSchema and ProcessSchemaLocation validation flags are set. 
    2) Schemas added during validation add new types and can change the validation outcome of the document being validated. As a result, external schemas should only be resolved from trusted sources.
    3) Validation error messages may expose sensitive content model information. Validation error and warning messages are handled using the ValidationEventHandler delegate, or are exposed as an XmlSchemaValidationException if no event handler is provided to the XmlReaderSettings object (validation warnings do not cause an XmlSchemaValidationException to be thrown). This content model information should not be exposed in untrusted scenarios. Validation warning messages are suppressed by default and can be reported by setting the ReportValidationWarnings flag.
    4) The SourceUri property of an XmlSchemaValidationException returns the URI path to the schema file that caused the exception. The SourceUri property should not be exposed in untrusted scenarios.
    5) Disabling the ProcessIdentityConstraints flag (enabled by default) is recommended when validating, untrusted, large XML documents in high availability scenarios against a schema with identity constraints over a large part of the document.
    6) XmlReaderSettings objects can contain sensitive information such as user credentials. You should be careful when caching XmlReaderSettings objects, or when passing the XmlReaderSettings object from one component to another.
    7) DTD processing is disabled by default. If you enable DTD processing, you need to be aware of including DTDs from untrusted sources and possible denial of service attacks. Use the XmlSecureResolver to restrict the resources that the XmlReader can access.
    8) Do not accept supporting components, such as NameTable, XmlNamespaceManager, and XmlResolver objects, from an untrusted source.
    
    基础设施列完了,那我们应该如何开始这验证的旅程呢?

    首先,创建一XmlReaderSettings对象,在XmlReaderSettings对象中设置好相应的属性,我们希望使用Schema来验证读入的xml文件, 把对象的ValidationType属性设置成类型,指定验证事件处理器,并把Schema的文件名和其命名空间加入到Schema集合中:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType 
= ValidationType.Schema;
settings.Schemas.Add("urn:example-schema""example.xsd");
settings.ValidationEventHandler 
+= new ValidationEventHandler(checkCallback);


    然后,把这个XmlReaderSettings对象作为XmlReader类的Create方法的参数,获得得一个XmlReader对象

XmlReader reader = XmlReader.Create("example_data.xml", settings);

    这样,这个XmlReader对象在执行Read方法时,会使用我们指定的Schema文件验证其读取的xml文件:

while (reader.Read()) 
{
  …
}

    我们把所有的的代码合在一块: 

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType 
= ValidationType.Schema;
settings.Schemas.Add(
"urn:example-schema""example.xsd");
settings.ValidationEventHandler 
+= new ValidationEventHandler(checkCallback);
XmlReader reader 
= XmlReader.Create("example_data.xml", settings);
try
{
    
while (reader.Read()) 
    
{
        …
    }

}

finally
{
    reader.Close();
}

    
    看看,是不是比以前一个节点一个节点、一个属性一个属性读取、判断的方法要简洁多了?