标签:
很早以前看过一句话:“XML就象空气”,在企业应用开发中XML是一个重要的数据交换标准。而XSD则可以用来校验XML的数据格式是否正确。
一个典型的XSD文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- edited with XMLSpy v2013 (http://www.altova.com) by () --> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="AWB"> <xs:annotation> <xs:documentation>运单</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="AWB-INFO" minOccurs="1" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element name="AWBPRE"> <xs:annotation> <xs:documentation>运单前缀只有输入3位数字</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:positiveInteger"> <xs:totalDigits value="3"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="AWBNO"> <xs:annotation> <xs:documentation>运单号只能输入8位数字</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:positiveInteger"> <xs:totalDigits value="8"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="PART-INFO"> <xs:complexType> <xs:sequence> <xs:element name="PARTICIPANT" minOccurs="2" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>物流参与者至少要有2个</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="TYPE"> <xs:annotation> <xs:documentation>物流参考者类型,只能是A/S/C其中之一</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="C"/> <xs:enumeration value="S"/> <xs:enumeration value="A"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="ADDRESS" type="AddressType"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="AddressType"> <xs:sequence> <xs:element name="Name" type="xs:string"/> <xs:element name="Street" type="xs:string"/> <xs:element name="City" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
看到这一大段xml,第一反应通常是头晕,幸好这些内容不用纯手动编写,已经有很多现成的工具,比如XmlSpy可以方便的以GUI方式,通过轻点鼠标,拖拖拉拉就能完成XSD的开发。
这是XmlSpy中XSD的可视化设计界面,还能切换不同的视图,比如下面这样:
对于首次接触XmlSpy的朋友,强烈推荐看下安装目录下的Tutorial.pdf,这是一个不错的入门教程,30分钟以前绝对可以快速浏览一遍。
C#中可以方便的使用XSD来验证xml文件的正确性,示例代码如下:
using System; using System.Xml; namespace XsdValidate { class Program { static void Main(string[] args) { string xmlFile = @"C:\Users\jimmy.yang\Desktop\XMLSPY\TEST\sample.xml"; string xsdFile = @"C:\Users\jimmy.yang\Desktop\XMLSPY\TEST\sample.xsd"; var xsdValidateResult = ValidateXml(xmlFile, xsdFile); if (xsdValidateResult.Item1) { Console.WriteLine("校验通过!"); } else { Console.WriteLine("校验失败,原因:\n" + xsdValidateResult.Item2); } Console.Read(); } /// <summary> /// 使用xsd验证xml是否正确 /// </summary> /// <param name="xmlFilePath">xml文件路径</param> /// <param name="xsdFilePath">xsd文件路径</param> /// <returns></returns> static Tuple<bool, string> ValidateXml(string xmlFilePath, string xsdFilePath) { Tuple<bool, string> result = new Tuple<bool, string>(true, ""); XmlReaderSettings st = new XmlReaderSettings(); st.ValidationType = ValidationType.Schema; st.Schemas.Add(null, xsdFilePath); //设置验证xml出错时的事件。 st.ValidationEventHandler += (obj, e) => { result = new Tuple<bool, string>(false, e.Message); }; XmlReader xr = XmlReader.Create(xmlFilePath, st); while (xr.Read()) { if (xr.IsStartElement()) { xr.Read(); } } xr.Close(); return result; } } }
注意:如果节点采用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类代码如下:
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.18331 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using System.Xml.Serialization; // // This source code was auto-generated by xsd, Version=4.0.30319.1. // /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class AWB { private AWBAWBINFO aWBINFOField; private AWBPARTICIPANT[] pARTINFOField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute("AWB-INFO")] public AWBAWBINFO AWBINFO { get { return this.aWBINFOField; } set { this.aWBINFOField = value; } } /// <remarks/> [System.Xml.Serialization.XmlArrayAttribute("PART-INFO")] [System.Xml.Serialization.XmlArrayItemAttribute("PARTICIPANT", IsNullable=false)] public AWBPARTICIPANT[] PARTINFO { get { return this.pARTINFOField; } set { this.pARTINFOField = value; } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] public partial class AWBAWBINFO { private string aWBPREField; private string aWBNOField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger")] public string AWBPRE { get { return this.aWBPREField; } set { this.aWBPREField = value; } } /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger")] public string AWBNO { get { return this.aWBNOField; } set { this.aWBNOField = value; } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class AddressType { private string nameField; private string streetField; private string cityField; /// <remarks/> public string Name { get { return this.nameField; } set { this.nameField = value; } } /// <remarks/> public string Street { get { return this.streetField; } set { this.streetField = value; } } /// <remarks/> public string City { get { return this.cityField; } set { this.cityField = value; } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] public partial class AWBPARTICIPANT { private AWBPARTICIPANTTYPE tYPEField; private AddressType aDDRESSField; /// <remarks/> public AWBPARTICIPANTTYPE TYPE { get { return this.tYPEField; } set { this.tYPEField = value; } } /// <remarks/> public AddressType ADDRESS { get { return this.aDDRESSField; } set { this.aDDRESSField = value; } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] public enum AWBPARTICIPANTTYPE { /// <remarks/> C, /// <remarks/> S, /// <remarks/> A, }
xsd命令还能直接根据xml生成xsd文件,使用方法如下:
xsd c:\sampe.xml /out:c:\
这样会根据sample.xml在c:\生成sample.xsd文件
作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
标签:
原文地址:http://www.cnblogs.com/rainbow70626/p/4714968.html