XmlSpy / XSD 以及 验证

很早以前看过一句话:“XML就象空气”,在企业应用开发中XML是一个重要的数据交换标准。而XSD则可以用来校验XML的数据格式是否正确。

一个典型的XSD文件如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!-- edited with XMLSpy v2013 (http://www.altova.com) by  () -->
 3 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
 4     <xs:element name="AWB">
 5         <xs:annotation>
 6             <xs:documentation>运单</xs:documentation>
 7         </xs:annotation>
 8         <xs:complexType>
 9             <xs:sequence>
10                 <xs:element name="AWB-INFO" minOccurs="1" maxOccurs="1">
11                     <xs:complexType>
12                         <xs:sequence>
13                             <xs:element name="AWBPRE">
14                                 <xs:annotation>
15                                     <xs:documentation>运单前缀只有输入3位数字</xs:documentation>
16                                 </xs:annotation>
17                                 <xs:simpleType>
18                                     <xs:restriction base="xs:positiveInteger">
19                                         <xs:totalDigits value="3"/>
20                                     </xs:restriction>
21                                 </xs:simpleType>
22                             </xs:element>
23                             <xs:element name="AWBNO">
24                                 <xs:annotation>
25                                     <xs:documentation>运单号只能输入8位数字</xs:documentation>
26                                 </xs:annotation>
27                                 <xs:simpleType>
28                                     <xs:restriction base="xs:positiveInteger">
29                                         <xs:totalDigits value="8"/>
30                                     </xs:restriction>
31                                 </xs:simpleType>
32                             </xs:element>
33                         </xs:sequence>
34                     </xs:complexType>
35                 </xs:element>
36                 <xs:element name="PART-INFO">
37                     <xs:complexType>
38                         <xs:sequence>
39                             <xs:element name="PARTICIPANT" minOccurs="2" maxOccurs="unbounded">
40                                 <xs:annotation>
41                                     <xs:documentation>物流参与者至少要有2个</xs:documentation>
42                                 </xs:annotation>
43                                 <xs:complexType>
44                                     <xs:sequence>
45                                         <xs:element name="TYPE">
46                                             <xs:annotation>
47                                                 <xs:documentation>物流参考者类型,只能是A/S/C其中之一</xs:documentation>
48                                             </xs:annotation>
49                                             <xs:simpleType>
50                                                 <xs:restriction base="xs:string">
51                                                     <xs:enumeration value="C"/>
52                                                     <xs:enumeration value="S"/>
53                                                     <xs:enumeration value="A"/>
54                                                 </xs:restriction>
55                                             </xs:simpleType>
56                                         </xs:element>
57                                         <xs:element name="ADDRESS" type="AddressType"/>
58                                     </xs:sequence>
59                                 </xs:complexType>
60                             </xs:element>
61                         </xs:sequence>
62                     </xs:complexType>
63                 </xs:element>
64             </xs:sequence>
65         </xs:complexType>
66     </xs:element>
67     <xs:complexType name="AddressType">
68         <xs:sequence>
69             <xs:element name="Name" type="xs:string"/>
70             <xs:element name="Street" type="xs:string"/>
71             <xs:element name="City" type="xs:string"/>
72         </xs:sequence>
73     </xs:complexType>
74 </xs:schema>

看到这一大段xml,第一反应通常是头晕,幸好这些内容不用纯手动编写,已经有很多现成的工具,比如XmlSpy可以方便的以GUI方式,通过轻点鼠标,拖拖拉拉就能完成XSD的开发。

这是XmlSpy中XSD的可视化设计界面,还能切换不同的视图,比如下面这样:

对于首次接触XmlSpy的朋友,强烈推荐看下安装目录下的Tutorial.pdf,这是一个不错的入门教程,30分钟以前绝对可以快速浏览一遍。

C#中可以方便的使用XSD来验证xml文件的正确性,示例代码如下:

 1 using System;
 2 using System.Xml;
 3 
 4 namespace XsdValidate
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             string xmlFile = @"C:\Users\jimmy.yang\Desktop\XMLSPY\TEST\sample.xml";
11             string xsdFile = @"C:\Users\jimmy.yang\Desktop\XMLSPY\TEST\sample.xsd";
12 
13             var xsdValidateResult = ValidateXml(xmlFile, xsdFile);
14 
15             if (xsdValidateResult.Item1)
16             {
17                 Console.WriteLine("校验通过!");
18             }
19             else
20             {
21                 Console.WriteLine("校验失败,原因:\n" + xsdValidateResult.Item2);
22             }
23             Console.Read();
24 
25         }
26 
27         /// <summary>
28         /// 使用xsd验证xml是否正确
29         /// </summary>
30         /// <param name="xmlFilePath">xml文件路径</param>
31         /// <param name="xsdFilePath">xsd文件路径</param>
32         /// <returns></returns>
33         static Tuple<bool, string> ValidateXml(string xmlFilePath, string xsdFilePath)
34         {
35             Tuple<bool, string> result = new Tuple<bool, string>(true, "");
36             XmlReaderSettings st = new XmlReaderSettings();
37             st.ValidationType = ValidationType.Schema;
38             st.Schemas.Add(null, xsdFilePath);
39 
40             //设置验证xml出错时的事件。
41             st.ValidationEventHandler += (obj, e) =>
42             {
43                 result = new Tuple<bool, string>(false, e.Message);
44             };
45 
46             XmlReader xr = XmlReader.Create(xmlFilePath, st);
47             while (xr.Read())
48             {
49                 if (xr.IsStartElement())
50                 {
51                     xr.Read();
52                 }
53             }
54             xr.Close();
55             return result;
56         }
57     }
58 }

注意:如果节点采用pattern,即正则表达式验证,比如

<xs:restriction base="xs:string">
         <xs:pattern value="^\d{8}$"></xs:pattern>
</xs:restriction>

XMLSpy中,该节点必须填写"^12345678$"才能验证通过,而如果用.NET/JAVA写代码验证的话,^、$能自动识别为"匹配字符开头/结尾"

XSD还能方便的生成c#类,有二种方法:

1、XMLSpy里先打开一个XSD文件,然后 DTD/Schema->Generate Program Code,接下来按提示操作即可

注:XMLSpy生成的c#类太过于复杂,我个人觉得有点啰嗦

2、直接使用vs.net自带的xsd命令

vs.net命令行下,输入

xsd "xsd文件所在的路径" /classes /out:"cs文件的输出目录"

即可生成对应的cs类 ,文中最开头的xsd生成的cs类代码如下:

  1 //------------------------------------------------------------------------------
  2 // <auto-generated>
  3 //     This code was generated by a tool.
  4 //     Runtime Version:4.0.30319.18331
  5 //
  6 //     Changes to this file may cause incorrect behavior and will be lost if
  7 //     the code is regenerated.
  8 // </auto-generated>
  9 //------------------------------------------------------------------------------
 10 
 11 using System.Xml.Serialization;
 12 
 13 // 
 14 // This source code was auto-generated by xsd, Version=4.0.30319.1.
 15 // 
 16 
 17 
 18 /// <remarks/>
 19 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
 20 [System.SerializableAttribute()]
 21 [System.Diagnostics.DebuggerStepThroughAttribute()]
 22 [System.ComponentModel.DesignerCategoryAttribute("code")]
 23 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
 24 [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
 25 public partial class AWB {
 26     
 27     private AWBAWBINFO aWBINFOField;
 28     
 29     private AWBPARTICIPANT[] pARTINFOField;
 30     
 31     /// <remarks/>
 32     [System.Xml.Serialization.XmlElementAttribute("AWB-INFO")]
 33     public AWBAWBINFO AWBINFO {
 34         get {
 35             return this.aWBINFOField;
 36         }
 37         set {
 38             this.aWBINFOField = value;
 39         }
 40     }
 41     
 42     /// <remarks/>
 43     [System.Xml.Serialization.XmlArrayAttribute("PART-INFO")]
 44     [System.Xml.Serialization.XmlArrayItemAttribute("PARTICIPANT", IsNullable=false)]
 45     public AWBPARTICIPANT[] PARTINFO {
 46         get {
 47             return this.pARTINFOField;
 48         }
 49         set {
 50             this.pARTINFOField = value;
 51         }
 52     }
 53 }
 54 
 55 /// <remarks/>
 56 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
 57 [System.SerializableAttribute()]
 58 [System.Diagnostics.DebuggerStepThroughAttribute()]
 59 [System.ComponentModel.DesignerCategoryAttribute("code")]
 60 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
 61 public partial class AWBAWBINFO {
 62     
 63     private string aWBPREField;
 64     
 65     private string aWBNOField;
 66     
 67     /// <remarks/>
 68     [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger")]
 69     public string AWBPRE {
 70         get {
 71             return this.aWBPREField;
 72         }
 73         set {
 74             this.aWBPREField = value;
 75         }
 76     }
 77     
 78     /// <remarks/>
 79     [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger")]
 80     public string AWBNO {
 81         get {
 82             return this.aWBNOField;
 83         }
 84         set {
 85             this.aWBNOField = value;
 86         }
 87     }
 88 }
 89 
 90 /// <remarks/>
 91 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
 92 [System.SerializableAttribute()]
 93 [System.Diagnostics.DebuggerStepThroughAttribute()]
 94 [System.ComponentModel.DesignerCategoryAttribute("code")]
 95 public partial class AddressType {
 96     
 97     private string nameField;
 98     
 99     private string streetField;
100     
101     private string cityField;
102     
103     /// <remarks/>
104     public string Name {
105         get {
106             return this.nameField;
107         }
108         set {
109             this.nameField = value;
110         }
111     }
112     
113     /// <remarks/>
114     public string Street {
115         get {
116             return this.streetField;
117         }
118         set {
119             this.streetField = value;
120         }
121     }
122     
123     /// <remarks/>
124     public string City {
125         get {
126             return this.cityField;
127         }
128         set {
129             this.cityField = value;
130         }
131     }
132 }
133 
134 /// <remarks/>
135 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
136 [System.SerializableAttribute()]
137 [System.Diagnostics.DebuggerStepThroughAttribute()]
138 [System.ComponentModel.DesignerCategoryAttribute("code")]
139 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
140 public partial class AWBPARTICIPANT {
141     
142     private AWBPARTICIPANTTYPE tYPEField;
143     
144     private AddressType aDDRESSField;
145     
146     /// <remarks/>
147     public AWBPARTICIPANTTYPE TYPE {
148         get {
149             return this.tYPEField;
150         }
151         set {
152             this.tYPEField = value;
153         }
154     }
155     
156     /// <remarks/>
157     public AddressType ADDRESS {
158         get {
159             return this.aDDRESSField;
160         }
161         set {
162             this.aDDRESSField = value;
163         }
164     }
165 }
166 
167 /// <remarks/>
168 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
169 [System.SerializableAttribute()]
170 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
171 public enum AWBPARTICIPANTTYPE {
172     
173     /// <remarks/>
174     C,
175     
176     /// <remarks/>
177     S,
178     
179     /// <remarks/>
180     A,
181 }

xsd命令还能直接根据xml生成xsd文件,使用方法如下:

xsd c:\sampe.xml /out:c:\

这样会根据sample.xml在c:\生成sample.xsd文件

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

ExtJs学习笔记(22)-XTemplate + WCF 打造无刷新数据分页

ExtJs的Grid组件虽然不管从哪一方面来讲,都称得上是很好很强大,但是总会有一些应用场景并不需要这么多功能,比如网站的留言列表,开发者只想要一个简单的<li...

24950
来自专栏丑胖侠

《Drools7.0.0.Final规则引擎教程》第5章 session使用说明

KieSession是用来与规则引擎进行交互的会话。在Drools 7当中分有状态的session和无状态的session:KieSession和Statele...

29770
来自专栏技术博客

一步一步学Linq to sql(十):多层架构MVC WCF Linq

 A,MVC网站项目 MvcOperation:留言簿表现层  B,类库项目 Contract:定义数据访问服务的契约  C,类库项目 Service:定义数据...

11520
来自专栏技术小讲堂

ASP.NET AJAX(4)__客户端访问WebService服务器端释放WebService方法客户端访问WebService客户端访问PageMethod错误处理复杂数据类型使用基础客户端代理的

服务器端释放WebService方法 编写一个普通的WebService 为WebService类添加自定义的属性标记__ScriptServiceAttrib...

29170
来自专栏.NET开发那点事

使用Microsoft Fakes进行单元测试(2)

接上一篇使用Microsoft Fakes进行单元测试(1) 下面进行Shim的演示。 2.使用Shim替换静态方法 假设我们需要一个工具方法用来格式化当前时...

22790
来自专栏菩提树下的杨过

ExtJs学习笔记(23)-ScriptTagProxy+XTemplate+WCF跨域取数据

ajax应用中跨域一直是一个非常麻烦的问题,目前也有一些解决办法,但要么比较麻烦,要么就不具备通用性,幸好ExtJs里的ScriptTagProxy提供了跨域读...

26980
来自专栏DOTNET

.Net多线程编程—误用点分析

1 共享变量问题 错误写法: 所有的任务可能会共享同一个变量,所以输出结果可能会一样。 1 public static void Error() 2 { 3 ...

35280
来自专栏码农阿宇

.Net Core中利用TPL(任务并行库)构建Pipeline处理Dataflow

在学习的过程中,看一些一线的技术文档很吃力,而且考虑到国内那些技术牛人英语都不差的,要向他们看齐,所以每天下班都在疯狂地背单词,博客有些日子没有更新了,见谅见谅...

11010
来自专栏张善友的专栏

自定义Unity对象生命周期管理集成ADO.NET Entity Framework

在Unity中,从Unity 取得的实例为 Transient。如果你希望使用多线程方式,就需要在组成时使用lifecycle参数,这时候取出的组件就不再是同一...

37180
来自专栏菩提树下的杨过

socket中的byte消息格式设计

这二天在研究webabcd的socket多人聊天室,想尝试增加一些功能,比如:允许用户除发送文字外,还能发送图片或文件。 问题: socket发送数据时,只能发...

20470

扫码关注云+社区

领取腾讯云代金券