2011-01-03 48 views
9

Tôi có tệp XSD và tệp XML, làm cách nào để kiểm tra xem XML có nằm trong lược đồ đúng như tệp XSD không?xác thực lược đồ XML

tôi biết có chức năng xác thực trong lớp XmlDocument nhưng cần trình xử lý sự kiện và tất cả những gì tôi cần là đúng hoặc sai.

P.S. Tôi đang làm việc trongVisual Studio 2010.

Trả lời

22

có một cách dễ dàng hơn nhiều để làm điều đó:

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; 
    } 
} 

Tái bút: Tôi không viết này trong VS do đó có thể là từ đó không trong trường hợp nhạy cảm, nhưng mã này hoạt động!

+0

Cảm ơn, Đó chính xác là những gì tôi cần! – M3NTA7

+0

Thật đơn giản khi so sánh với các giải pháp khác ngoài kia, cảm ơn! – JBeagle

+0

'validate' phải bằng chữ in hoa đầu tiên ... – realsonic

3

Bạn có thể tạo cá thể XmlReader xác thực bằng cách sử dụng lớp XmlReaderSettings và phương thức Tạo.


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; } 
     } 
    } 
} 

Mã trên sẽ ném ngoại lệ nếu lược đồ không hợp lệ hoặc không thể deserialize xml. rootType là loại phần tử gốc trong phân cấp lớp tương đương.


Ví dụ: Schema tại địa chỉ: XML Schema Tutorial. Lưu tệp dưới dạng D:\SampleSchema.xsd.

Run xsd.exe:

  1. Open 'Start Menu> All Programs> Microsoft Visual Studio 2010> Visual Studio Tools> Visual Studio 2010 Command Prompt'
  2. Trong cửa sổ lệnh, gõ: xsd.exe /c /out:D:\ "D:\SampleSchema.xsd"
  3. tùy chọn xsd: /out tùy chọn để chỉ định thư mục đầu ra, /c là để chỉ định công cụ để tạo các lớp học
  4. Hệ thống phân cấp lớp đầu ra có tại D:\SampleSchema.cs
  5. Các tạo hệ thống cấp bậc lớp trông một số điều như thế này,

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

Thêm lớp cho dự án visual studio.
Đối với mẫu xsd ở trên, lớp gốc là note.
Gọi phương thức, thông tin


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

thêm:

+0

nhưng sử dụng trong "schemaFilePath" ở đâu? bạn chỉ cần kiểm tra xem đó là exsits ... – aharon

+0

Điều này sẽ không xác nhận bất cứ điều gì vì không có ValidationFlags được thiết lập. Điều này sẽ chỉ deserialize xml. –

+0

tôi không cần desirialization. tôi cần xác nhận ... – aharon

1

Bạn có thể làm một cái gì đó như thế này.

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

} 

Giản đồ.

<?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> 
+0

làm thế nào tôi có thể làm điều đó mà không cần nhập tất cả xml vào cuộc gọi chức năng? và vòng lặp "while" phải làm gì? và cách hàm sử dụng lược đồ? – aharon

+0

Bạn có thể chuyển một đường dẫn đến hàm Validate và thực hiện 'var reader = XmlReader.Create (path, settings);' thay vì 'var reader = XmlReader.Create (new StringReader (xml), settings);' –

+0

ok. nhưng vòng lặp "while" phải làm gì? và cách hàm sử dụng lược đồ? – aharon

Các vấn đề liên quan