• XmlSpy / XSD以及验证


    很早以前看过一句话:“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:Usersjimmy.yangDesktopXMLSPYTESTsample.xml";
                string xsdFile = @"C:Usersjimmy.yangDesktopXMLSPYTESTsample.xsd";
    
                var xsdValidateResult = ValidateXml(xmlFile, xsdFile);
    
                if (xsdValidateResult.Item1)
                {
                    Console.WriteLine("校验通过!");
                }
                else
                {
                    Console.WriteLine("校验失败,原因:
    " + 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 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    使用WCF 测试客户端测试你的WCF服务
    使用Fiddler解析WCF RIA Service传输的数据
    SqlServer中BULK INSERT用法简介
    Silverlight的安全性初探
    使用Apache cxf 和Spring在Tomcat下发布Webservice指南
    Spring 3 MVC And XML Example
    设计与开发 JAXWS 2.0 Web 服务
    如何高效、准确、自动识别网页编码
    Spring 3 MVC And RSS Feed Example
    Spring 3 MVC And JSON Example
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/4714968.html
Copyright © 2020-2023  润新知