模式验证 XML

Posted

技术标签:

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

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

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

附:我在 Visual Studio 2010 中工作。

【问题讨论】:

【参考方案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

    打开“开始菜单 > 所有程序 > Microsoft Visual Studio 2010 > Visual Studio 工具 > Visual Studio 2010 命令提示符” 在命令提示符下,键入:xsd.exe /c /out:D:\ "D:\SampleSchema.xsd" xsd选项:/out选项指定输出目录,/c指定生成类的工具 输出类层次结构存在于D:\SampleSchema.cs 生成的类层次结构看起来像这样,

//------------------------------------------------------------------------------
// 
//     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));

更多信息:

Validation Against XML Schema (XSD) with the XmlValidatingReader XML Schema Definition Tool (Xsd.exe)

【讨论】:

这不会验证任何东西,因为没有设置 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 中写的,所以可能会有不区分大小写的单词,但这段代码有效!

【讨论】:

谢谢,这正是我所需要的! 与其他解决方案相比非常简单,谢谢!

以上是关于模式验证 XML的主要内容,如果未能解决你的问题,请参考以下文章

模式验证 XML

基础-XML常用的两种验证模式

在Python中使用XML模式进行验证

自定义 XML 文档的验证模式

要针对多个 xsd 模式验证 XML

针对多个模式定义验证 XML 文件