« | September 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | |
|
统计 |
blog名称: 日志总数:9 评论数量:4 留言数量:1 访问次数:72458 建立时间:2004年11月2日 |
| 
|
W3CHINA Blog首页 管理页面 写新日志 退出
[.net XML]在.net中验证XML |
不少人问起怎么在程序中验证XML,这里我拿.net来做个简单例子,其实这些在MSDN中都能查到的,拿出来让大家清楚应该用什么类吧。
我这里举个没有名称空间的例子(简单是关键,呵呵)。我们可以看一下这样的XSD文件(命名为key.xsd):
<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="root"> <xs:annotation> <xs:documentation>Comment describing your root element</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="Num" type="xs:integer"/> <xs:element name="Name" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element></xs:schema>一个root根元素,其下一个sequence,包含一个xs:integer的Num节点,一个是xs:string 的Name节点。
下来写一个XML:
<?xml version="1.0" encoding="UTF-8"?><root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="key.xsd"> <Num>1</Num> <Name>sum</Name></root>这个是符合上面的规范的,而且因为是没有名称空间限制,所以用了xsi:noNamespaceSchemaLocation="key.xsd"来连接XSD。
下面就要写程序来验证看看了,我这里用的是C#:
using System;using System.Xml;using System.Xml.Schema;
因为要验证,所以需要Schema的验证类XmlValidatingReader来完成,这个类是继承自XmlReader,是一个只向前读的游标。类似于SAX,但是这是一个基于拉模型的,而SAX是基于推模型,事件驱动的。包含了System.Xml.Schema我们才更好的应用XmlValidatingReader。
下来在Main函数中,我们声明一个XmlTextReader来读取XML:
XmlTextReader objXmlTReader = new XmlTextReader("key.xml");
读取本地的key.xml,就是上面的那个。再建立一个XmlValidatingReader并与objXmlTReader 建立关联,用它来验证。
XmlValidatingReader objXmlVReader = new XmlValidatingReader(objXmlTReader);
因为在验证中出错我们要及时得到错误信息,我们要向XmlValidatingReader注册一个报错函数来得到错误消息。首先我们先写一个静态函数(不是必须是静态,只是在例子中使用方便):
public static void ErrConsole(object sender,ValidationEventArgs e) { Console.WriteLine("The XML Validation Err:"+ e.Message ); }
然后紧接着刚才的代码加上:
objXmlVReader.ValidationEventHandler +=new ValidationEventHandler(ErrConsole);
好,下一步就要让objXmlVReader去读取我们的XML并去验证:
try { while(objXmlVReader.Read()); } catch(XmlException e) { Console.WriteLine("Err:"+e.Message); } finally { objXmlVReader.Close(); }
就在 while(objXmlVReader.Read());中objXmlVReader会读取XML并验证,如果出错就会调用ErrConsole将错误信息打出来,很简单吧。整个程序就是这么多,你自己可以加上一些提示信息。在MSDN中寻找“验证”你会得到比着更清楚的信息。如果你要循环验证或验证次数较多,那么就用XmlSchemaCollection去保存xsd,节省来回读取硬盘的时间。这个在MSDN中也有详细介绍。
不过这个验证方法还是有问题的,有些Schema是不能验证的,如:
key.xsd:
<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="staffs"> <xs:complexType> <xs:sequence> <xs:element name="Staff"> <xs:complexType> <xs:attribute name="Id" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="Role" type="staffType"> <xs:keyref name="staffkey2" refer="staffKey"> <xs:selector xpath="."/> <xs:field xpath="Staff"/> </xs:keyref> </xs:element> </xs:sequence> </xs:complexType> <xs:key name="staffKey"> <xs:selector xpath="Staff"/> <xs:field xpath="@Id"/> </xs:key> </xs:element> <xs:complexType name="staffType"> <xs:sequence> <xs:element name="Staff"/> </xs:sequence> </xs:complexType></xs:schema>
key.xml:
<?xml version="1.0" encoding="UTF-8"?><staffs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="key.xsd"> <Staff Id="1"/> <Role> <Staff>1</Staff> </Role></staffs>
你把staff的Id改得和下面的staff不同,那么XMLSPY会报错,但是objXmlVReader就没那么厉害了,它还会美滋滋的告诉你,你的文档是合格的,呵呵。
|
阅读全文(2436) | 回复(0) | 编辑 | 精华 |
|