2011-01-03 2 views
9

Ich habe eine XSD-Datei und eine XML-Datei, wie kann ich überprüfen, ob das XML im richtigen Schema wie die XSD-Datei ist?Schema Validierung XML

Ich weiß, es gibt eine Validierungsfunktion in der Klasse XmlDocument, aber es benötigt einen Event-Handler und alles, was ich brauche, ist wahr oder falsch.

P.S. Ich arbeite in Visual Studio 2010.

Antwort

22

gibt es einen viel einfachen Weg, es zu tun:

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: Ich habe dies in VS nicht geschrieben, so könnte es sein Wort, das nicht in Groß- und Kleinschreibung, aber dieser Codes funktioniert!

+0

Danke, genau das habe ich auch gebraucht! – M3NTA7

+0

Verblüffend einfach im Vergleich zu anderen Lösungen, danke! – JBeagle

+0

'validate' sollte mit Großbuchstaben beginnen ... – realsonic

3

Sie können eine validierende XmlReader-Instanz mithilfe der XmlReaderSettings-Klasse und der Create-Methode erstellen.


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

Der obige Code wird eine Ausnahme, wenn das Schema ist ungültig oder es ist nicht in der Lage deserialisieren die XML werfen. rootType ist der Typ des Wurzelelements in der entsprechenden Klassenhierarchie.


Beispiel: Schema auf: XML Schema Tutorial. Speichern Sie die Datei unter D:\SampleSchema.xsd.

Run xsd.exe:

  1. Open 'Startmenü> Alle Programme> Microsoft Visual Studio 2010> Visual Studio Tools> Visual Studio 2010-Eingabeaufforderung'
  2. In der Eingabeaufforderung: xsd.exe /c /out:D:\ "D:\SampleSchema.xsd"
  3. xsd options: /out Die Option gibt das Ausgabeverzeichnis an, /c gibt das Werkzeug zum Generieren von Klassen an
  4. Die Ausgabeklassenhierarchie ist untervorhanden
  5. Die erzeugte Klassenhierarchie sieht ein Ding wie diese,

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

die Klasse in das Visual Studio-Projekt hinzufügen.
Für das obige xsd-Beispiel ist die Stammklasse note.
Rufen Sie die Methode,


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

Weitere Informationen:

+0

aber wo ist die Verwendung in der "schemaFilePath"? Sie überprüfen nur, dass es exsits ist ... – aharon

+0

Dies wird nichts validieren, da keine ValidationFlags gesetzt sind. Dies wird das XML einfach deserialisieren. –

+0

Ich brauche keine Desirialisierung. Ich brauche Validierung ... – aharon

1

Sie so etwas tun könnte.

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

} 

Das Schema.

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

Wie kann ich es tun, ohne alle xml zum Funktionsaufruf einzugeben? und was soll die "while" schleife machen? und wie nutzt die Funktion das Schema? – aharon

+0

Sie könnten einen Pfad zur Validate-Funktion übergeben und 'var reader = XmlReader.Create (Pfad, Einstellungen);' statt 'var reader = XmlReader.Create (neuer StringReader (xml), Einstellungen);' –

+0

ok. aber was soll die "while" schleife machen? und wie nutzt die Funktion das Schema? – aharon