Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

[转] C#验证XML --- 转自 http://www.cnblogs.com/jonescheng/archive/2011/11/25/2263931.html

C# Schema验证Xml的若干种方法

 
Schema是用于描述和规范XML文档的逻辑结构的一种语言,它最大的作用就是验证XML文件逻辑结构的正确性。可以理解成与DTD(文档类型定义)功 能差不多,但是Schema在当前的WEB开发环境下优越很多。因为它本身就是一个有效的XML文档,因而可以更直观地了解XML的结构。除此之 外,Schema支持命名空间,内置多种简单和复杂的数据类型,并支持自定义数据类型。由于存在这么多的优点,所以Schema渐渐成为XML应用的统一 规范。
 

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Schema;
using System.Xml;
using System.IO;
namespace MyClass1
{
    public class TestSchema
    {
        private static string Namespace = "http://www.beyondbit.com";
        private static bool isValid = true;
        public static bool ValidationSchema(string filename)
        {
            XmlTextReader r = new XmlTextReader(filename);
            XmlValidatingReader v = new XmlValidatingReader(r);
            v.ValidationType = ValidationType.Schema;
            v.ValidationEventHandler += new ValidationEventHandler(MyValidationEventHandler);
            while (v.Read())
            {
                // Can add code here to process the content.
            }
            v.Close();
            return isValid;
        }
        public static bool ValidationSchemaNew(string filename, string schema)
        {
            XmlSchemaSet xsSet = new XmlSchemaSet();
            try
            {
                xsSet.Add(Namespace, schema);
            }
            catch(Exception ex) {
                string a = ex.Message;
                return false;
            }
            // 定义公文模式的使用方式
            XmlReaderSettings xrSetting = new XmlReaderSettings();
            xrSetting.ValidationType = ValidationType.Schema;
            // 关联验证读取器与架构集合
            xrSetting.Schemas = xsSet;
            // 添加发生错误时的事件处理程序
            xrSetting.ValidationEventHandler += new ValidationEventHandler(MyValidationEventHandler);
            // 使用最新的方式来构建可进行校验的读取器并构造验证读取器
            XmlReader xr = XmlReader.Create(filename, xrSetting);
            // 循环检测所有的文档节点
            while (xr.Read())
            {
            }
            xr.Close();
            return isValid;
        }
        public static bool ValidationSchemaNow(string xmlstring, string schemastring)
        {
            //构建待验证数据的XmlReader对象
            XmlReader xmlDataReader = XmlTextReader.Create(new StringReader(xmlstring));
            //构建标准的XmlReader对象
            XmlReader xmlSchemaReader = XmlTextReader.Create(new StringReader(schemastring));
            // 定义公文模式的使用方式
            XmlReaderSettings xrSetting = new XmlReaderSettings();
            try
            {
                xrSetting.Schemas.Add(null, xmlSchemaReader);
            }
            catch (System.Xml.Schema.XmlSchemaException ex)
            {
                string b = ex.Message;
                return false;
            }
            xrSetting.ValidationType = ValidationType.Schema;
            xrSetting.ValidationEventHandler += new ValidationEventHandler(MyValidationEventHandler);
            XmlReader xr = XmlReader.Create(xmlDataReader, xrSetting);
            while (xr.Read())
            {
            }
            xr.Close();
            return isValid;
        }
        /// <summary>
        /// 验证处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private static void MyValidationEventHandler(object sender, ValidationEventArgs args)
        {
            if (args.Severity == XmlSeverityType.Warning)
            {
                WriteErrorLogs("Validation Warning:   " + args.Message);
            }
            else
            {
                WriteErrorLogs("Validation Error:   " + args.Message);
            }
            isValid = false;
        }
        /// <summary>
        /// 记录错误日志
        /// </summary>
        /// <param name="ss"></param>
        private static void WriteErrorLogs(string ss)
        {
            StreamWriter sw = null;
            try
            {
                sw = new StreamWriter(@"C:\test_error.txt", true, Encoding.UTF8);
                sw.WriteLine("[" + DateTime.Now.ToString() + "]" + ss);
                sw.Flush();
                sw.Close();
            }
            catch { sw.Close(); }
        }
    }
}

使用XmlValidatingReader类验证读取Xml文档
   .Net程序集System.Xml包含了许多类,这些类用于在.Net平台上提供Xml功能。 XmlValidatingReader类(XmlReader类的一种实现)就是其中的一种。在将xml文档或Xml片段读入系统时,该类提供验证支 持。它实现 DTD、XML 数据简化 (XDR) 架构和 XML 架构定义语言 (XSD) 架构等规范所定义的有效性约束。

  1、构造XmlValidatingReade类对象实例
  初始化XmlValidatingReader类的新实例有多种方法,最常用的一种是传入XmlReader类型的参数:  public XmlValidatingReader( XmlReader reader);
XmlValidatingReader vReader=new XmlValidatingReader(XmlTextReader xtr);  


  作为XmlReader的具体实现之一,XmlTextReader类提供对Xml文档的快速、只前进、无缓存的读取,而 XmlValidatingReader可以使用从XmlTextReader所返回的所有内容,并进一步提供验证支持。当然,如果一切正常,该过程不会 造成信息丢失,从给定的 XmlReader 返回的所有节点和属性也都从此验证读取器返回。未从基础读取器返回的新节点可能由此读取器添加(例如,实体引用的默认属性和子级)。

  2、指定验证类型
  从前面已经能知道,有三种规范用于对xml文档执行验证。它们是DTD、XDR及XmlSchema。所以,在执行验证之前,需要确定验证的类型,这通过设置ValidatingReader类的ValidationType属性来完成:  

vReader.ValidationType=ValidationType.Schema.  


  这行代码将验证声明为XSD Schema。

  3、使用XmlSchemaCollection类缓存架构

  如果需要根据XDR或者XSD Schema进行验证,可以使用XmlSchemaCollection类来缓存架构,这样将可以提高性能。XmlSchemaCollection类的 Add方法加载架构,同时,架构会与命名空间 URI 关联。对于"XML 架构"的源文件(.xsd)来说,这通常会是架构的 targetNamespace 属性。  

XmlSchemaCollection xsc=new XmlSchemaCollection();
Xsc.Add("http://www.tuha.net","vschema.xsd");  


  当然,如果架构内联于Xml文档中,就不需要这样做了。

  4、关联架构缓存

  在向XmlSchemaCollection中添加完schema之后,XmlValidatingReader并不能自动识别并使用schema, 还需要将两者关联起来。通过使用读取器的 Schemas 属性引用缓存在 XmlSchemaCollection 中的架构文件来完成这一过程:  

vReader.Schemas.Add(xsc);  



  5、ValidationEventHandler事件处理程序回调
  在使用ValidatingReader执行验证读取Xml文档时,可能发生意外。这时,可以通过ValidationEventHandler 回调报告验证错误和警告。ValidationEventHandler 事件用于设置一个事件处理程序以接收有关文档类型定义 (DTD)、数据简化 XML (XDR) 和 XML 架构定义语言 (XSD) 架构验证错误的信息。

  不过,如果不提供 ValidationEventHandler,你依然可以使用通用的异常处理机制来捕捉错误。当发生分析错误时,将通过引发 XmlException 报告错误。如果发生验证错误,将引发 XmlSchemaException。当然,任何一种异常,将无法重新启动 XmlValidatingReader。

  指定事件及回调用遵循通用的做法:通过+=将XmlValidatingReader与事件处理程序ValidationEventHandler连接起来:  

vReader.ValidationEventHandler+=new ValidationEventHandler(vCallback);  



  参数vCallback是回调处理程序的方法名称,这个方法必须包含一个ValidationEventArgs类型的参 数,ValidationEventArgs 类具有针对以下各项的属性:文本消息,表示 Error 或 Warning 的 XmlSeverityType 枚举,以及包含与特定验证错误关联的 XmlSchemaException 信息的异常。  


private void vCallback(object sender,ValidationEventArgs args)
{
//发生错误时的处理代码
}  


  这一步不是必须的,如果你能保证错误不会发生或者发生就发生去吧!

  6、执行验证读操作

  做完以上准备工作后,你可以使用XmlValidatingReader类的读方法开始验证读取Xml文档了。可以是 Read、ReadInnerXml、ReadOuterXml 中的任一种以及其他将改变接点的方法,如Skip()方法。这时,都将发生验证。  

While(vReader.Read())
{
//处理读取的内容
}  



  三、实例
  综合以上知识,下面创建一个Windows Console控制台应用程序,用于在商务领域中处理产品数据,一般地,不同公司产品数据将遵循一定的格式,这里通过XSD

  Xsd,该架构文件对xml文档提供结构信息,用于在数据交换时遵循一致的标准 
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Products" targetNamespace="http://www.tuha.net" elementFormDefault="qualified"
xmlns="http://www.tuha.net" xmlns:mstns="http://www.tuha.net"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Products" type="a1"></xs:element>
<xs:complexType name="b1">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Type" type="xs:string" />
<xs:element name="Usefor" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="a1">
<xs:sequence maxOccurs="unbounded">
<xs:element name="Item" type="b1" />
</xs:sequence>
</xs:complexType>
</xs:schema> 
根据上面的架构文件,下面构造了一个产品数据xml文档,这里使用了产品库内容的部分段落,为方便测试,让它成为了一个完整的xml文档: 
<?xml version="1.0" encoding="utf-8" ?>
<roducts xmlns="http://www.tuha.net">
<Item>
<Name>Talking Online</Name>
<Type>Fittings</Type>
<Usefor>Communicate</Usefor>
</Item>
<Item>
<Name>Debugging Online</Name>
<Type>rofessional</Type>
<Usefor>Machine</Usefor>
</Item>
</Products> 
下面的应用程序对xml文档进行处理,并验证其数据是否是符合该架构的有效的! 
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
namespace MyXmlValidationgReader
{
class Class1
{
static bool sign=true;
[STAThread]
static void Main(string[] args)
{
XmlTextReader xtr=null;
XmlValidatingReader xvr=null;
string xmlFile="http://www.cnblogs.com/Products.xml";//xml源文档
string xsdFile="http://www.cnblogs.com/Products.xsd";//xsd架构文档
xtr=new XmlTextReader(xmlFile);//构造非验证读取器
XmlSchemaCollection xsc=new XmlSchemaCollection();//构造Schema架构缓存
xsc.Add("http://www.tuha.net",xsdFile);//在缓存中添加架构文件及对应名字空间
xvr=new XmlValidatingReader(xtr);//构造验证读取器
xvr.Schemas.Add(xsc);//关联验证读取器与架构集合
xvr.ValidationType=ValidationType.Schema;//设置验证类型为Schema架构
xvr.ValidationEventHandler+=new ValidationEventHandler(vCallback);
//发生错误时的事件处理程序
while(xvr.Read())//执行读操作
{
}
Console.Write("Finished! "+sign.ToString());
}
private static void vCallback(object sender,ValidationEventArgs args)
//错误回调程序
{
sign=false;//改变标记
}
}

posted on 2012-06-20 15:23  RJ  阅读(1214)  评论(0)    收藏  举报

导航