2011-01-03 27 views
9

Tengo un archivo XSD y un archivo XML, ¿cómo puedo verificar si el XML está en el esquema correcto como el archivo XSD?validación de esquema XML

sé que hay una función de validación en la clase XmlDocument, pero necesita un controlador de eventos y todo lo que necesito es verdadero o falso.

P.S. Estoy trabajando en Visual Studio 2010.

Respuesta

22

hay una manera fácil tanto para hacerlo:

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: No me escribió esto en VS por lo que podría ser la palabra que no está en mayúsculas y minúsculas, pero funciona esto códigos!

+0

¡Gracias, eso es exactamente lo que necesitaba también! – M3NTA7

+0

Sorprendentemente simple en comparación con otras soluciones, ¡gracias! – JBeagle

+0

'validate' debe ser con mayúscula inicial ... – realsonic

3

Puede crear una instancia de validación de XmlReader utilizando la clase XmlReaderSettings y el método Create.


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

El código anterior una excepción si el esquema es válido o no es capaz de deserializar el XML. rootType es el tipo del elemento raíz en la jerarquía de clases equivalente.


Ejemplo: esquema en: XML Schema Tutorial. Guarde el archivo como D:\SampleSchema.xsd.

Run xsd.exe:

  1. 'menú Inicio> Todos los programas> Microsoft Visual Studio 2010> Visual Studio Tools> Visual Studio 2010 Símbolo del sistema' Open
  2. En el símbolo del sistema, escriba: xsd.exe /c /out:D:\ "D:\SampleSchema.xsd"
  3. opciones xsd: /out opción es especificar el directorio de salida, /c es especificar la herramienta para generar clases
  4. La jerarquía de clase de salida está presente en D:\SampleSchema.cs
  5. La jerarquía de clases generada se ve algo como esto,

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

Añadir la clase al proyecto de Visual Studio.
Para la muestra de xsd anterior, la clase de raíz es note.
Llame al método,


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

Más información:

+0

pero ¿dónde está el uso en "schemaFilePath"? simplemente verifique que se encuentre ... – aharon

+0

Esto no validará nada ya que no se establecen ValidationFlags. Esto simplemente deserializará el xml. –

+0

no necesito desirialización. Necesito validación ... – aharon

1

Usted podría hacer algo como esto.

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

} 

El esquema.

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

¿cómo puedo hacerlo sin ingresar el todo xml a la llamada de función? y qué se supone que debe hacer el ciclo "while"? y cómo la función usa el esquema? – aharon

+0

Puede pasar una ruta a la función Validar y hacer 'var reader = XmlReader.Create (ruta, configuración);' en lugar de 'var reader = XmlReader.Create (new StringReader (xml), settings);' –

+0

bien. pero, ¿qué se supone que debe hacer el ciclo "while"? y cómo la función usa el esquema? – aharon

Cuestiones relacionadas