假使说XML是一个数据库,那么XSD就是这个数据库的结构。由此可见,XSD是如此重要,如果没有它,我们如何声明以及验证我们需要的XML数据文件的格式和合法性呢?那是不可能完成的任务,如果你将XML数据文件当作普通的文本文件去验证的话。

我用下面一个例子来解释如何定义XSD以及如何使用它来验证

1. 首先来看一下我们的数据文件

<?xml version="1.0" encoding="utf-8" ?> <Order> <OrderID>10248</OrderID> <OrderDate>2009-01-01</OrderDate> <Details> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>1</ProductID> <Quantity>2</Quantity> <UnitPrice>20</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>1</ProductID> <Quantity>2</Quantity> <UnitPrice>20</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>1</ProductID> <Quantity>2</Quantity> <UnitPrice>20</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>1</ProductID> <Quantity>2</Quantity> <UnitPrice>20</UnitPrice> </OrderItem> </Details> </Order>

这是一个典型的订单数据。我们来分析一下这份文档

  • 必须有OrderID,而且必须是整数型,integer
  • 必须有OrderDate,而且必须是日期型,datetime
  • 必须有至少一个OrderItem,这个Item必须包含四部分信息
    • ItemNumber,integer
    • ProductID,integer
    • Quantity,double
    • UnitPrice,double

2. 我们来定义一个XSD文件。有关XSD的知识很多,有兴趣的朋友可以参考下面这个链接

http://www.w3school.com.cn/schema/index.asp

<?xml version="1.0" encoding="utf-8"?> <xs:schema id="OrderSchema" targetNamespace="http://tempuri.org/OrderSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/OrderSchema.xsd" xmlns:mstns="http://tempuri.org/OrderSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xs:element name="Order"> <xs:complexType> <xs:sequence> <xs:element name="OrderID" type="xs:integer"></xs:element> <xs:element name="OrderDate" type="xs:date"></xs:element> <xs:element name="Details"> <xs:complexType> <xs:group ref="OrderItemGroup" minOccurs="1" maxOccurs="unbounded"></xs:group> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <!-- 定义一个OrderItem的复杂类型 --> <xs:group name="OrderItemGroup"> <xs:sequence> <xs:element name="OrderItem"> <xs:complexType> <xs:sequence> <xs:element name="ItemNumber" type="xs:integer"></xs:element> <xs:element name="ProductID" type="xs:integer"></xs:element> <xs:element name="Quantity" type="xs:double"></xs:element> <xs:element name="UnitPrice" type="xs:double"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:group> </xs:schema>
 
【备注】这个架构也可以通过Visual Studio的“XML”菜单=》“创建架构”得到。

3. 下面来看看如何使用该架构对数据文件进行验证

.NET Framework并没有提供简单易行的验证方法,我们需要写一些代码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="btValidateFile" runat="server" Text="验证文档" OnClick="ValidateFile" /> </div> </form> </body> </html>

代码文件

using System; using System.Text; using System.Xml; namespace WebApplication1 { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } StringBuilder sb = null; protected void ValidateFile(object sender, EventArgs e) { string dataFile = Server.MapPath("Order.xml"); string schemaFile = Server.MapPath("OrderSchema.xsd"); string namespaceUrl = "http://tempuri.org/OrderSchema.xsd"; XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas.Add(namespaceUrl, schemaFile); settings.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(settings_ValidationEventHandler); string errorMessage="这不是一个合乎规范的数据文件"; sb = new StringBuilder(); XmlReader reader = XmlReader.Create(dataFile, settings); try { reader.MoveToContent(); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Document && reader.NamespaceURI != namespaceUrl) { Response.Write(errorMessage); break; } } } catch (XmlException ex) { sb.AppendFormat("{0}<br />", ex.Message); } finally { reader.Close(); } if (sb.Length == 0) Response.Write("该文档是合法的"); else Response.Write(sb.ToString()); } void settings_ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs e) { sb.AppendFormat("{0}<br />", e.Message); } } }

准备就绪之后,我们可以立即按下F5键进行调试。因为现在文档确实是合法的,所以点击按钮之后,会输出一个正确的消息。

我们故意将文档改成下面这样子

<?xml version="1.0" encoding="utf-8" ?> <Order xmlns="http://tempuri.org/OrderSchema.xsd"> <OrderID>1</OrderID> <OrderDate>2009-1-1</OrderDate> <Details> </Details> </Order>
我们没有提供OrderItem,同时,OrderDate的格式是不正确的。(XML里面的日期必须是类似这样的格式:YYYY-MM-DD)
此时我们去点击页面中的按钮,就会发现下面这样的错误提示
 
 
小结一下:我们可以通过XMLReader的读取,验证XML文档的合法性。关键点在于我们指定给这个XMLReader一些Settings
这些代码还可以封装一下,以免更好的重复利用。
之前有一位XML方面的MVP也专门写了一个组件,可以方便地做验证。请参考http://msdn.microsoft.com/zh-cn/library/aa468554.aspx

4. 对于有命名空间的情况,则会复杂很多

我已经多次提到如果有命名空间的情况,XML的操作(包括验证和转换等等)都会变得更加复杂。但仍然需要面对这个现实

我们假设,XML数据文件是类似下面的格式

<?xml version="1.0" encoding="utf-8" ?> <Order xmlns:d="http://www.xizhang.com"> <d:OrderID>1</d:OrderID> <OrderDate>2009-01-01</OrderDate> <Details> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>2</ProductID> <Quantity>3</Quantity> <UnitPrice>3</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>2</ProductID> <Quantity>3</Quantity> <UnitPrice>3</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>2</ProductID> <Quantity>3</Quantity> <UnitPrice>3</UnitPrice> </OrderItem> </Details> </Order>

与之前的文档相比,这个文档多了一个命名空间的信息,在OrderID上面,我们加上了命名空间的限定

我们通过点击菜单:“XML”=》“创建架构”来生成架构。它会生成两个文件,分别如下

Order.xsd

<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:d="http://www.xizhang.com" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://www.xizhang.com" /> <xs:element name="Order"> <xs:complexType> <xs:sequence> <xs:element ref="d:OrderID" /> <xs:element name="OrderDate" type="xs:date" /> <xs:element name="Details"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="OrderItem"> <xs:complexType> <xs:sequence> <xs:element name="ItemNumber" type="xs:unsignedByte" /> <xs:element name="ProductID" type="xs:unsignedByte" /> <xs:element name="Quantity" type="xs:unsignedByte" /> <xs:element name="UnitPrice" type="xs:unsignedByte" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>

还有一个Order1.xsd

<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:tns="http://www.xizhang.com" attributeFormDefault="unqualified"
elementFormDefault="qualified" targetNamespace="http://www.xizhang.com" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="OrderID" type="xs:unsignedByte" /> </xs:schema>

我们注意到,在Order.xsd中,用了一个ref的方式,实现了一个元素的引用。其他它是引用了Order1.xsd中的OrderID元素。

但是,我们怎么知道是这样的引用关系呢?我们并没有在Order.XSD中看到这个关系呢

其实是有的。你可以在Order.xsd文件中,按下F4键,查看属性

点击架构右侧的那个按钮

下面我们来测试一下,带有命名空间的情况下如何验证

  • 首先,你应该选中Order.xsd和Order1.xsd,并将它们保存到项目根目录。因为他们默认是被创建在临时文件夹的
  • 为Order.xsd添加一个TargetNamespace
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:d="http://www.xizhang.com" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs=http://www.w3.org/2001/XMLSchema 
targetNamespace="http://www.xizhang.com"> <xs:import namespace="http://www.xizhang.com" /> <xs:element name="Order"> <xs:complexType> <xs:sequence> <xs:element ref="d:OrderID" /> <xs:element name="OrderDate" type="xs:date" /> <xs:element name="Details"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="OrderItem"> <xs:complexType> <xs:sequence> <xs:element name="ItemNumber" type="xs:unsignedByte" /> <xs:element name="ProductID" type="xs:unsignedByte" /> <xs:element name="Quantity" type="xs:unsignedByte" /> <xs:element name="UnitPrice" type="xs:unsignedByte" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
  • 修改一下代码
 string dataFile = Server.MapPath("Order.xml"); string schemaFile = Server.MapPath("Order.xsd"); string namespaceUrl = "http://www.xizhang.com"; XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas.Add(namespaceUrl, schemaFile); settings.Schemas.Add(namespaceUrl, Server.MapPath("Order1.xsd"));//这里要加第二个文件
 
 
 
同样道理,我们故意去修改一下数据文件
<?xml version="1.0" encoding="utf-8" ?> <Order xmlns:d="http://www.xizhang.com"> <d:OrderID>1</d:OrderID> <OrderDate>2009/1/1</OrderDate> <Details> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>2</ProductID> <Quantity>3</Quantity> <UnitPrice>3</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>2</ProductID> <Quantity>3</Quantity> <UnitPrice>3</UnitPrice> </OrderItem> <OrderItem> <ItemNumber>1</ItemNumber> <ProductID>2</ProductID> <Quantity>3</Quantity> <UnitPrice>3</UnitPrice> </OrderItem> </Details> </Order>
 

小结:

这样我们就完成了对包含有命名空间的XML数据文件的验证工作。这个操作需要两个XML架构文件,他们之间形成一个引用关系。如果有多个不同的命名空间,则可能会有多个辅助的架构文件。

需要注意的是,在Order.xsd中,最好是用下面的语法去定义schemaLocation

<xs:import namespace="http://www.xizhang.com" schemaLocation="Order1.xsd" />

如果这样定义了,代码中就可以省略掉添加第二个架构文件的代码

//settings.Schemas.Add(namespaceUrl, Server.MapPath("Order1.xsd"));//这里要加第二个文件

 

本文由作者:陈希章 于 2009/6/19 23:17:33 发布在:http://www.cnblogs.com/chenxizhang/

本文版权归作者所有,可以转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

使用架构(XSD)验证XML文件的更多相关文章

  1. C# xsd 验证 XML数据有效性 问题

    使用XSD进行批量数据导入时生成的XML数据有效性这样的功能已经不是第一次做了,之前做的时候都没有碰到什么问题,这些天在开发中遇到了一个很头痛的问题就是无论XSD文件规则怎么写,验证都是通过的. 下面 ...

  2. 根据框架的dtd或xsd生成xml文件

    下载Schema文件 首先要下载框架官网下的xsd或者xml文件,例如Spring官网地址,schema里面的就是xsd文件 Myeclipse中配置 我用的Myeclipse纯净版6.5,Windo ...

  3. C# XSD校验XML文件的代码

    /// <summary> /// XSD文件校验XML /// </summary> /// <returns></returns> public A ...

  4. C# 利用Xsd验证xml

    最近做项目时,用到了xml的序列化与反序列化, 发现最好用xsd来验证xml, 因为反序列化xml不校验xsd. 方法:xmlData变量为xml字符串 MemoryStream ms = new M ...

  5. 用xsd验证xml

    using System; using System.Text; using System.Xml; namespace WebApplication1 { public partial class ...

  6. 检查dtd和Xschema文件限制下的xml文件是否符合的Java文件

    先来xml文件: 1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE orders SY ...

  7. XSD(XML Schema Definition)用法实例介绍以及C#使用xsd文件验证XML格式

    XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD),作用是定义 XML 文档的合法构建模块,类似 DTD,但更加强大. 作用有: ①定义 ...

  8. C# 使用xsd文件验证XML 格式是否正确

    C# 使用xsd文件验证XML 格式是否正确 核心示例代码: //创建xmlDocument XmlDocument doc = new XmlDocument(); //创建声明段 如<?xm ...

  9. 28.XSD(XML Schema Definition)用法实例介绍以及C#使用xsd文件验证XML格式

    转自https://www.cnblogs.com/gdjlc/archive/2013/09/08/3308229.html XML Schema 语言也称作 XML Schema 定义(XML S ...

随机推荐

  1. sphinx 全配置

    ## 数据源src1 source src1 { ## 说明数据源的类型.数据源的类型可以是:mysql,pgsql,mssql,xmlpipe,odbc,python ## 有人会奇怪,python ...

  2. 【转】 Understanding Component-Entity-Systems

    http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-sy ...

  3. [转]Table-Driven and Data Driven Programming

    What is Table-Driven and Data-Driven Programming? Data/Table-Driven programming is the technique of ...

  4. 转载: SQL Server中的索引

    http://www.blogjava.net/wangdetian168/archive/2011/03/07/347192.html 1 SQL Server中的索引 索引是与表或视图关联的磁盘上 ...

  5. WebRTC录音(2)-录音文件转换成WAV格式

    以下是源码,大路货,从网上找的. 但是,这个东西在MacOS上是有问题的,原因在最后,都是泪啊. #include <stdio.h> #include <string.h> ...

  6. sublime text 2 + Dev-C++/MinGW 组合配置更方便快捷的 C/C++ 编译环境(原创)

    首先看一下配置后的效果: 1.直接在底部文本框中显示运行结果(不需要从键盘输入的时候使用): 2.在cmd中运行结果(需要从键盘输入的时候使用): 快捷键说明: 运行: 在底部文本栏显示结果:Ctrl ...

  7. 横向滚动条展示 css

    <div class="shuaixuan" style="overflow:hidden;">    <div style="ov ...

  8. SQL参数化查询--最有效可预防SQL注入攻击的防御方式

    参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值. 在使用参 ...

  9. Apache的虚拟主机配置

    使用虚拟主机要先取消中心主机,注释掉DocumentRoot #DocumentRoot "/www/htdoc" 虚拟主机的单独配置: 用户认证 访问日志 错误日志 别名 脚本别 ...

  10. MySQL二进制日志的备份和恢复

    二进制日志:记录数据库修改的相关操作,作用是即时点回复,主从复制 可以按时间滚动,也可以按大小滚动 server-id:服务器身份标识 一.二进制文件的删除方法,千万不要手动删除 PURGE BINA ...