2010-12-10 21 views
5

Oto moja funkcja.Walidacja schematu XML kończy się niepowodzeniem z MemoryStream w C#

Jeśli przekazujesz MemoryStream do XmlReadera, czasami nie sprawdza poprawnych plików xml. Mam obiekt XmlDocument przechowywany w pamięci, chcę go sprawdzić wobec plików schematu xsd dostarczonych przez użytkownika końcowego.

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

Jesteś pewien, że XML jest ważna, gdy walidacja nie powiedzie? Wyjątek sprawdzania poprawności powinien Ci powiedzieć, dlaczego tak się nie stało. – Oded

Odpowiedz

2

Może to działa: http://www.experts-exchange.com/Programming/Languages/.NET/Visual_CSharp/Q_23387252.html
Działa How to validate, on runtime, xml against xsd without save the xsd file on local folder?

Edit 1: Poprawiono kod podany, teraz kod działa tak jak powinien, potwierdzone 2 z moich plików. Powodem, dla którego popełniono błąd, jest fakt, że podczas próby sprawdzenia poprawności i Xsd z samym sobą i elementem głównym nie było. Sprawdź rozwiązanie, aby przekonać się sam.

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

Dlaczego nie używasz pozostałych dwóch skomentowanych metod w swoim kodzie zamiast strumienia pamięci?

[UPDATE]:

Spróbuj odpowiedź:

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

Ponieważ oferowane rozwiązanie nie mogę używać z klasami, które już mam. –

+0

Czy mogę zapytać o powód przyjęcia? To tylko sugestia, a nie odpowiedź! –

+0

Mogłeś opublikować komentarz, a nie odpowiedź –

Powiązane problemy