【问题标题】:schema validation XML模式验证 XML
【发布时间】:2011-06-02 19:33:36
【问题描述】:

我有一个 XSD 文件和一个 XML 文件,如何检查 XML 是否像 XSD 文件一样在正确的架构中?

我知道XmlDocument 类中有一个验证函数,但它需要一个事件处理程序 我只需要对或错。

附:我在 Visual Studio 2010 中工作。

【问题讨论】:

    标签: c# xml xsd schema


    【解决方案1】:

    您可以使用 XmlReaderSettings 类和 Create 方法创建一个验证 XmlReader 实例。

    
    private bool ValidateXml(string xmlFilePath, string schemaFilePath, string schemaNamespace, Type rootType)
    {
        XmlSerializer serializer = new XmlSerializer(rootType);
    
        using (var fs = new StreamReader(xmlFilePath, Encoding.GetEncoding("iso-8859-1")))
        {
            object deserializedObject;
            var xmlReaderSettings = new XmlReaderSettings();
            if (File.Exists(schemaFilePath))
            {
                //select schema for validation  
                xmlReaderSettings.Schemas.Add(schemaNamespace, schemaPath); 
                xmlReaderSettings.ValidationType = ValidationType.Schema;
                try
                {
                using (var xmlReader = XmlReader.Create(fs, xmlReaderSettings))
                {                
                    if (serializer.CanDeserialize(xmlReader))
                    {
                        return true;
                        //deserializedObject = serializer.Deserialize(xmlReader);
                    }
                    else
                    {
                        return false;
                    }
                }
                }
                catch(Exception ex)
                { return false; }
            }
        }
    }
    

    如果架构无效或无法反序列化xml,上述代码将抛出异常。 rootType 是等效类层次结构中根元素的类型。


    示例: 架构位于:XML Schema Tutorial。将文件另存为D:\SampleSchema.xsd

    运行xsd.exe

    1. 打开“开始菜单 > 所有程序 > Microsoft Visual Studio 2010 > Visual Studio 工具 > Visual Studio 2010 命令提示符”
    2. 在命令提示符下,键入:xsd.exe /c /out:D:\ "D:\SampleSchema.xsd"
    3. xsd选项:/out选项指定输出目录,/c指定生成类的工具
    4. 输出类层次结构存在于D:\SampleSchema.cs
    5. 生成的类层次结构看起来像这样,
    
    //------------------------------------------------------------------------------
    // 
    //     This code was generated by a tool.
    //     Runtime Version:2.0.50727.4952
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // 
    //------------------------------------------------------------------------------
    
    using System.Xml.Serialization;
    
    // 
    // This source code was auto-generated by xsd, Version=2.0.50727.3038.
    // 
    
    
    /// 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [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 note {
    
        private string toField;
    
        private string fromField;
    
        private string headingField;
    
        private string bodyField;
    
        /// 
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string to {
            get {
                return this.toField;
            }
            set {
                this.toField = value;
            }
        }
    
        /// 
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string from {
            get {
                return this.fromField;
            }
            set {
                this.fromField = value;
            }
        }
    
        /// 
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string heading {
            get {
                return this.headingField;
            }
            set {
                this.headingField = value;
            }
        }
    
        /// 
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string body {
            get {
                return this.bodyField;
            }
            set {
                this.bodyField = value;
            }
        }
    }
    

    将该类添加到 Visual Studio 项目中。
    对于上面的 xsd 示例,根类是 note
    调用方法,

    
    bool isXmlValid = ValidateXml(@"D:\Sample.xml", 
                                  @"D:\SampleSchema.xsd", 
                                  @"http://www.w3.org/2001/XMLSchema", 
                                  typeof(note));
    

    更多信息:

    【讨论】:

    • 这不会验证任何东西,因为没有设置 ValidationFlags。这只会反序列化 xml。
    • 我应该输入什么作为 rootType?
    • rootType 是从 xsd 文件创建的类模型的根元素的类型。例如,如果您创建一个类模型(使用 .NET 的 xsd.exe 工具),那么类型将为“Product”(对于@Steven 给出的示例 xsd)。
    • 使用 .NET 的 xsd 工具创建类层次结构。例如,如果架构文件位于 'D:\testSchema.xsd',则工具用法应为 > xsd /c /out:D:\ "D:\testSchema.xsd"。这是一个命令行工具。欲了解更多信息:msdn.microsoft.com/en-us/library/x6c1kb0s%28v=VS.100%29.aspx
    • 啊?与类型有什么联系?我想怎么写类型?
    【解决方案2】:

    你可以这样做。

    public class XmlValidator
    {
        private bool _isValid = true;
    
        public bool Validate(string xml)
        {
            _isValid = true;
    
            // Set the validation settings as needed.
            var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema };
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.ValidationEventHandler += ValidationCallBack;
    
            var reader = XmlReader.Create(new StringReader(xml), settings);
    
            while(reader.Read())
            {
                // process the content if needed
            }
    
            return _isValid;
        }
    
        private void ValidationCallBack(object sender, ValidationEventArgs e)
        {
            // check for severity as needed
            if(e.Severity == XmlSeverityType.Error)
            {
                _isValid = false;
            }
        }
    }
    
    class Program
    {
    
        static void Main(string[] args)
        {
            var validator = new XmlValidator();
    
            var result =
                validator.Validate(@"<?xml version=""1.0""?>
                     <Product ProductID=""1"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""schema.xsd"">
                         <ProductName>Chairs</ProductName>
                     </Product>");
    
    }
    

    架构。

    <?xml version="1.0"?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <xsd:element name="Product">
          <xsd:complexType>
             <xsd:sequence>
                <xsd:element name="ProductName" type="xsd:string"/>
             </xsd:sequence>
             <xsd:attribute name="ProductID" use="required" type="xsd:int"/>
          </xsd:complexType>
       </xsd:element>
    </xsd:schema>
    

    【讨论】:

    • 如何在不输入所有 xml 到函数调用的情况下做到这一点?以及“while”循环应该做什么?以及函数如何使用该方案?
    • 您可以将路径传递给 Validate 函数并执行 'var reader = XmlReader.Create(path, settings);'而不是 'var reader = XmlReader.Create(new StringReader(xml), settings);'
    • 好的。但是“while”循环应该做什么?以及函数如何使用该方案?
    • while循环解析xml文档,并在这个过程中验证xml。 xml 包含对架构的引用:w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""schema.xsd"">
    • 一个。在while循环中需要写什么代码?湾。如果我在代码中没有对架构的引用怎么办,它在属性中。它会工作吗?
    【解决方案3】:

    有一个非常简单的方法:

    private void ValidationCallBack(object sender, ValidationEventArgs e)
    {  
        throw new Exception();
    }
    
    public bool validate(string sxml)
    {
        try
        {
            XmlDocument xmld=new XmlDocument ();
            xmld.LoadXml(sxml);
            xmld.Schemas.Add(null,@"c:\the file location");
            xmld.validate(ValidationCallBack);
            return true;
        }
        catch
        {
            return false;
        }
    }
    

    P.S : 我不是在 VS 中写的,所以可能会有不区分大小写的单词,但这段代码有效!

    【讨论】:

    • 谢谢,这正是我所需要的!
    • 与其他解决方案相比非常简单,谢谢!
    猜你喜欢
    • 2010-11-22
    • 2013-05-22
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 2010-10-25
    相关资源
    最近更新 更多