2010-12-10 30 views
5

Aquí está mi función.La validación del esquema Xml falla con MemoryStream en C#

Si pasa MemoryStream a XmlReader, a veces no valida los archivos xml adecuados. Tengo el objeto XmlDocument almacenado en la memoria, quiero validarlo contra los archivos de esquema xsd proporcionados por el usuario final.

ValidateSchema1(string XMLPath, string XSDPath) 
    { 
     XmlDocument xmlDocument = new XmlDocument(); 

     xmlDocument.Load(XMLPath); 

      using (MemoryStream mstream = new MemoryStream()) 
      { 
       //StreamWriter writer = new StreamWriter(mstream); 
       xmlDocument.Save(mstream); 
       mstream.Seek(0, SeekOrigin.Begin); 
       XmlSchemaSet sc = new XmlSchemaSet(); 

       // Add the schema to the collection. 
       sc.Add(null, XSDPath); 

       // Set the validation settings. 
       XmlReaderSettings settings = new XmlReaderSettings(); 
       settings.ValidationType = ValidationType.Schema; 
       settings.Schemas = sc; 
       settings.ValidationEventHandler += ValidationCallBack; 

       // Create the XmlReader object. 

       // Not woking 
       XmlReader reader = XmlReader.Create(mstream, settings); 

       // Working 
       //XmlReader reader = XmlReader.Create(new StringReader(xmlDocument.InnerXml), settings); 

       // Working 
       //XmlReader reader = XmlReader.Create(XMLPath, settings); 

       // Parse the file. 
       while (reader.Read()) ; 
      } 

    } 
+2

¿Estás seguro de que el XML es válido cuando la validación falla? La excepción de validación debe decirle _por qué_ falló. – Oded

Respuesta

2

Esto podría funcionar: http://www.experts-exchange.com/Programming/Languages/.NET/Visual_CSharp/Q_23387252.html
Esto funciona How to validate, on runtime, xml against xsd without save the xsd file on local folder?

Edición 1: Se ha corregido el código que ya ha proporcionado, ahora el código funciona como debería, validado 2 de mis archivos. La razón por la que obtuviste el error es el hecho de que intentabas validar y Xsd consigo mismo y el elemento raíz no estaba allí. Por favor revise la solución para ver por usted mismo.

public void Xsd_whithout_saved() 
    { 
     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.Load(@"file.xsd"); 
     //In the futute, strArquivoInteiro will be fullfill by xsd comming from database as nvarchar(max) and I will //not be allowed to save as a file locally  
     string strArquivoInteiro = xmlDoc.OuterXml; 

     byte[] byteArray = Encoding.ASCII.GetBytes(strArquivoInteiro); 
     MemoryStream streamXSD = new MemoryStream(byteArray); 
     //<<< 
     streamXSD.Position = 0; 
     StreamReader readerXsd = new StreamReader(streamXSD); 

     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.ValidationEventHandler += this.MyValidationEventHandler; 

     settings.ValidationType = ValidationType.Schema; 
     settings.Schemas.Add(null, XmlReader.Create(readerXsd)); 
     settings.CheckCharacters = true; 

     XmlReader XmlValidatingReader = XmlReader.Create(@"file.xml", settings); 

     XmlTextReader Reader = new XmlTextReader(@"file.xsd"); 
     //Created another reader for xml to use for validation 
     XmlTextReader Reader2 = new XmlTextReader(@"file.xml"); 

     XmlSchema Schema = new XmlSchema(); 

     //IN THIS LINE I RECEIVED THE XmlException "Root Element is Missing" and I can't understand the reason 
     //This was the first problem, a xsd root element isn't equal to an xml root element , and you where trying to validate and xsd with xsd here, and of course the error. 
     Schema = XmlSchema.Read(Reader, MyValidationEventHandler); 

     XmlValidatingReader ValidatingReader = new XmlValidatingReader(Reader2); 

     ValidatingReader.ValidationType = ValidationType.Schema; 

     ValidatingReader.Schemas.Add(Schema); 

     try 
     { 

      XmlValidatingReader.Read(); 
      XmlValidatingReader.Close(); 

      ValidatingReader.ValidationEventHandler += MyValidationEventHandler; 

      while ((ValidatingReader.Read())) 
      { 

      } 

      ValidatingReader.Close(); 
     } 
     catch (Exception ex) 
     { 
      ValidatingReader.Close(); 
      XmlValidatingReader.Close(); 
     } 
    } 
0

¿Por qué no utilizar los otros dos métodos comentadas en el código en lugar de secuencia de memoria?

[ACTUALIZACIÓN]:

Pruebe esta respuesta:

public static bool ValidateXmlFromXsd(string xml, string xsdFile) 
    { 

     bool returned = false; 
     XmlValidatingReader reader = null; 
     XmlSchemaCollection myschema = new XmlSchemaCollection(); 
     ValidationEventHandler eventHandler = new ValidationEventHandler(ShowCompileErrors); 
     try 
     { 
      XmlParserContext context = new XmlParserContext(null, null, "", XmlSpace.None); 
      reader = new XmlValidatingReader(xml, XmlNodeType.Element, context); 
      myschema.Add("urn:schemas-microsoft-com:xml-msdata", xsdFile); 
      reader.ValidationType = ValidationType.Schema; 
      reader.Schemas.Add(myschema); 

      while (reader.Read()) { } 

      Console.WriteLine("Completed validating xmlfragment"); 
      returned = true; 
     } 
     catch (XmlException XmlExp) 
     { 
      Console.WriteLine(XmlExp.Message); 
     } 
     catch (XmlSchemaException XmlSchExp) 
     { 
      Console.WriteLine(XmlSchExp.Message); 
     } 
     catch (Exception GenExp) 
     { 
      Console.WriteLine(GenExp.Message); 
     } 
     finally 
     { 
      Console.Read(); 
     } 
     return returned; 
    } 
+0

Porque la solución ofrecida no puedo usar con las clases que ya tengo. –

+0

¿Puedo preguntar el motivo del voto a favor? ¡Es solo una sugerencia, no una respuesta! –

+0

Podría haber publicado un comentario, no una respuesta –

Cuestiones relacionadas