2010-12-10 61 views
5

這是我的功能。Xml架構驗證失敗,在C#中使用MemoryStream

如果您將MemoryStream傳遞給XmlReader,它有時不驗證正確的xml文件。我將XmlDocument對象存儲在內存中,我想根據最終用戶提供的xsd Schema文件對其進行驗證。

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

你確定XML是有效的驗證失敗時?驗證例外應該告訴你_why_失敗。 – Oded 2010-12-10 21:28:16

回答

2

這可能會實現: http://www.experts-exchange.com/Programming/Languages/.NET/Visual_CSharp/Q_23387252.html
這工作 How to validate, on runtime, xml against xsd without save the xsd file on local folder?

編輯1:固定你提供的代碼,現在該代碼的工作,因爲它應該的,經過驗證我的文件2。你得到這個錯誤的原因是你試圖驗證Xsd,而根本元素不在那裏。請檢查解決方案,看看你自己。

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

爲什麼不在代碼中使用其他兩個註釋掉的方法而不是內存流?

[更新]:

嘗試這樣的回答:

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

因爲我提供的解決方案不能與我已有的課程一起使用。 – 2011-12-16 12:46:09

+0

我可以問一下downvote的原因嗎?這只是一個建議,不是答案! – 2011-12-19 12:07:47

+0

您可以發表評論,而不是回答 – 2011-12-19 14:23:52