2011-01-03 9 views
9

Mam plik XSD i plik XML, jak mogę sprawdzić, czy XML jest w odpowiednim schemacie, jak plik XSD?sprawdzanie poprawności schematu XML

Wiem, że istnieje funkcja sprawdzania poprawności w klasie XmlDocument, ale potrzebna jest procedura obsługi zdarzeń , a wszystko, czego potrzebuję, to prawda lub fałsz.

P.S. Pracuję invisual Studio 2010.

Odpowiedz

22

jest znacznie łatwy sposób to zrobić:

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: Nie napisałem to w VS, więc nie może być słowo, które nie w przypadku wrażliwy, ale kody działa!

+0

Dzięki, to jest dokładnie to, czego potrzebowałem! – M3NTA7

+0

Niezwykle prosty w porównaniu do innych rozwiązań, dzięki! – JBeagle

+0

'validate' powinno być z kapitałem pierwszej litery ... – realsonic

3

Można tworzyć Walidujący instancję XmlReader użyciu klasy XmlReaderSettings i Utwórz metodę.


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

Powyższy kod wygeneruje wyjątek, jeśli schemat jest niepoprawny lub nie może deserializować xml. rootType to typ elementu głównego w równoważnej hierarchii klas.


przykład: schematu na: XML Schema Tutorial. Zapisz plik jako D:\SampleSchema.xsd.

Run xsd.exe:

  1. Otwórz 'Menu Start> Wszystkie programy> Microsoft Visual Studio 2010> Visual Studio Tools> Visual Studio 2010 Wiersz poleceń'
  2. W wierszu polecenia wpisz: xsd.exe /c /out:D:\ "D:\SampleSchema.xsd"
  3. Opcje xsd: /out opcja określa katalog wyjściowy, /c jest określenie narzędzia do generowania klas
  4. Hierarchia klasy wyjściowej jest obecna na D:\SampleSchema.cs
  5. Wygenerowany hierarchii klasa wygląda pewne rzeczy tak,

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

Dodaj klasę do projektu visual studio.
Dla powyższej próbki xsd klasą podstawową jest note.
wywołać metodę,


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

Więcej informacji:

+0

ale gdzie jest użycie w "schemaFilePath"? po prostu sprawdzasz, czy to jest exsits ... – aharon

+0

To nie sprawdzi niczego, ponieważ nie ustawiono opcji ValidationFlags. Spowoduje to deserializację xml. –

+0

Nie potrzebuję desirializacji. potrzebuję sprawdzania poprawności ... – aharon

1

Można zrobić coś takiego.

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

} 

Schemat.

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

jak mogę to zrobić bez wprowadzania całego xml do wywołania funkcji? i co powinna zrobić pętla "while"? i jak funkcja używa schematu? – aharon

+0

Możesz przekazać ścieżkę do funkcji sprawdzania poprawności i wykonaj polecenie "var reader = XmlReader.Create (ścieżka, ustawienia);" zamiast "var reader = XmlReader.Create (nowy StringReader (xml), ustawienia);" –

+0

ok. ale co powinna zrobić pętla "while"? i jak funkcja używa schematu? – aharon