【问题标题】:Xml Schema Validation fails with MemoryStream in C#C# 中的 MemoryStream 导致 Xml 架构验证失败
【发布时间】:2011-05-23 17:49:32
【问题描述】:

这是我的功能。

如果您将 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()) ;
          }

    }

【问题讨论】:

  • 验证失败时,您确定 XML 有效吗?验证异常应该告诉您为什么它失败了。

标签: c# xml validation xsd


【解决方案1】:

这可能有效: 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();
        }
    }

【讨论】:

    【解决方案2】:

    为什么不在代码中使用另外两个注释掉的方法而不是内存流?

    [更新]:

    试试这个答案:

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

    【讨论】:

    • 因为我提供的解决方案不能用于我已有的课程。
    • 请问投反对票的原因是什么?这只是一个建议,而不是答案!
    • 你可以发表评论,而不是答案
    • 我回家后试试这个。
    • 不幸的是没有。还有一个问题,你使用的几乎所有类都过时了,很快就会消失
    猜你喜欢
    • 2021-03-09
    • 2018-07-30
    • 2015-09-05
    • 2010-11-03
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多