手记

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人推荐
随时随地看视频
慕课网APP