【问题标题】:There is an error in XML Document (0,0)XML 文档中存在错误 (0,0)
【发布时间】:2017-05-10 16:28:52
【问题描述】:

我在这个问题上花费了无数个小时,并且尝试了很多不同的东西。一些背景... 我正在使用 C# 代码在 SSIS 模块中工作,以尝试反序列化 SOAP XML 流。我之前已经能够反序列化 XML 流,但是这个比我之前参与的要复杂得多。

我已经验证我用来填充我的流的字符串对于结果是正确的,我已经走到了尽头。

这是我用来尝试反序列化的方法。你可以看到我已经包含了几个注释掉的部分,以展示我用来尝试完成这项工作的一些其他方法:

private Envelope GetWebServiceResultFromStream(StreamReader str)
{

    bool b = true;
    Envelope xmlResponse = null;
    String xmlPayload = "";

   //Deserialize our XML
    try
    {
        //System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();

        //using (Stream savestream = str.BaseStream)
        //{
        //    xmlResponse = (Envelope)soapFormatter.Deserialize(savestream);
        //}


        System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(Envelope));

        using (Stream savestream = str.BaseStream)
        {
            StreamReader streamreader = new StreamReader(savestream, Encoding.UTF8);
            xmlPayload = streamreader.ReadToEnd();

            //xmlPayload = System.Security.SecurityElement.Escape(xmlPayload);

            //xmlPayload = xmlPayload.Replace("&", "&");
            //xmlPayload = xmlPayload.Replace("&", "&");
            xmlPayload = xmlPayload.Replace("'", "'");
            //xmlPayload = xmlPayload.Replace("soap:Envelope", "Envelope");


            File.WriteAllText(@"myxml.xml",xmlPayload);



            byte[] byteArray = Encoding.UTF8.GetBytes(xmlPayload);
            MemoryStream secondstream = new MemoryStream(byteArray);
            secondstream.Position = 0;

            xmlResponse = sr.Deserialize(secondstream) as Envelope;

            //xmlResponse = (Envelope)DeserializeFromXml<Envelope>(xmlPayload);

            //XmlDocument doc = new XmlDocument();
            //doc.Load(secondstream);
            //XmlNodeReader reader = new XmlNodeReader(doc);
            //using (reader)
            //{
            //    xmlResponse = sr.Deserialize(reader) as Envelope;
            //}


            //System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();


            //xmlResponse = (Envelope)soapFormatter.Deserialize(secondstream);


        }

        //XmlDocument xmlSoapRequest = new XmlDocument();
        //using (Stream savestream = str.BaseStream)
        //{
        //    using (StreamReader readStream = new StreamReader(savestream, Encoding.UTF8))
        //    {
        //        xmlSoapRequest.Load(readStream);
        //        xmlPayload = xmlSoapRequest.SelectSingleNode("//Envelope/Body/GetRequisitionByDateResponse/").InnerText;
        //    }
        //}

    }
    catch (Exception ex)
    {
        DumpException(ex);
        this.ComponentMetaData.FireInformation(54, "", "Failed to deserialize: " + ex.Message + " Inner: " + ex.InnerException + " Source: " + ex.Source, "", 43, ref b);
    }

    return xmlResponse;

}

public static T DeserializeFromXml<T>(string xml)
{
    T result;

    var ser = new XmlSerializer(typeof(T));
    using (var tr = new StringReader(xml))
    {
        result = (T)ser.Deserialize(tr);
    }
    return result;
}

我正在使用通过将响应提供给 XML 到 C# 转换器 (http://xmltocsharp.azurewebsites.net/) 生成的 c# 类。不幸的是,这些类似乎太复杂了,无法放在这里(帖子有 30k 字符限制),所以它被粘贴在这里: http://txt.do/d91eo

我还粘贴了一个示例响应: http://txt.do/d91eb

我咨询了 wsdl,似乎许多 DateTime 字段正在通过转换器读取为字符串。我不确定这是否是个问题,但我已尽力替换这些数据类型,但错误仍然存​​在。

这是我的错误截图: http://imgur.com/a/objJq

我尝试过的其他事情:

替换整个 xml 文档中的无效字符(我发现它已经在这样做了,除了某些“'”字符)。

已移除命名空间。

将所有类标记为可序列化。

SSIS 中的 Web 服务对象(引发错误并且不允许我输入任何要发送的变量)。

使用返回结果的许多变体重新生成类列表。

【问题讨论】:

    标签: c# xml soap ssis deserialization


    【解决方案1】:

    找到了

    首先将 UTF8 添加到 StreamReader 中:new StreamReader(FILENAME, Encoding.UTF8);

    这是你的根类

     [XmlRoot(ElementName = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
        public class Envelope
        {
        }
    

    这是你的第一行 XML

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    

    比较命名空间

    【讨论】:

    • 所以您是说我应该将根类上的命名空间更改为等于 xmlns:soap 命名空间?我试过了,连同额外的编码参数,我得到了同样的错误。也许我理解错了?
    • 是的。我上课了:“w3.org/2003/05/soap-envelope”。您是否在第 0 列或第 2 列出现错误?我首先在第 1 行第 0 列出现错误,这是由于编码。然后我在第 2 列得到了一个命名空间。之后我在信封中得到了空数据,但是信封被构建了。所以当你得到错误是 Envelope null?
    • 错误一直是(0,0),没有别的。 w3.org/2003/05/soap-envelope 本来就是这样,对吧?
    • 回答您的其他问题,是的,它们为空。但是,它在尝试反序列化时会抛出错误。
    • 然后确保你使用: StreamReader streamreader = new StreamReader(savestream, Encoding.UTF8);也尝试使用记事本打开文件。然后做SaveAs并且不保存。但请确保文件类型为 UTF8(不是 ANSI、Unicode 或 Unicode Big Endian)。
    【解决方案2】:

    以下代码无异常运行。由于大小限制,我不能包括课程。请注意类信封的命名空间,我将“-”替换为“/”。类 Envelope 已构造,但所有属性均为空,因为命名空间与 xml 不一致。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    
    
    namespace ConsoleApplication50
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                new Test();
    
            }
        }
        public class Test
        {
            const string FILENAME = @"c:\temp\test2.xml";
            public Test()
            {
                StreamReader reader = new StreamReader(FILENAME, Encoding.UTF8);
                GetWebServiceResultFromStream(reader);
            }
    
            private Envelope GetWebServiceResultFromStream(StreamReader str)
            {
    
                bool b = true;
                Envelope xmlResponse = null;
                String xmlPayload = "";
    
               //Deserialize our XML
                try
                {
                    //System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
    
                    //using (Stream savestream = str.BaseStream)
                    //{
                    //    xmlResponse = (Envelope)soapFormatter.Deserialize(savestream);
                    //}
    
    
                    System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(Envelope));
    
                    using (Stream savestream = str.BaseStream)
                    {
                        StreamReader streamreader = new StreamReader(savestream, Encoding.UTF8);
                        xmlPayload = streamreader.ReadToEnd();
    
                        //xmlPayload = System.Security.SecurityElement.Escape(xmlPayload);
    
                        //xmlPayload = xmlPayload.Replace("&amp;", "&");
                        //xmlPayload = xmlPayload.Replace("&", "&amp;");
                        xmlPayload = xmlPayload.Replace("'", "&apos;");
                        //xmlPayload = xmlPayload.Replace("soap:Envelope", "Envelope");
    
    
                        File.WriteAllText(@"myxml.xml",xmlPayload);
    
    
    
                        byte[] byteArray = Encoding.UTF8.GetBytes(xmlPayload);
                        MemoryStream secondstream = new MemoryStream(byteArray);
                        secondstream.Position = 0;
    
                        xmlResponse = sr.Deserialize(secondstream) as Envelope;
    
                        //xmlResponse = (Envelope)DeserializeFromXml<Envelope>(xmlPayload);
    
                        //XmlDocument doc = new XmlDocument();
                        //doc.Load(secondstream);
                        //XmlNodeReader reader = new XmlNodeReader(doc);
                        //using (reader)
                        //{
                        //    xmlResponse = sr.Deserialize(reader) as Envelope;
                        //}
    
    
                        //System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
    
    
                        //xmlResponse = (Envelope)soapFormatter.Deserialize(secondstream);
    
    
                    }
    
                    //XmlDocument xmlSoapRequest = new XmlDocument();
                    //using (Stream savestream = str.BaseStream)
                    //{
                    //    using (StreamReader readStream = new StreamReader(savestream, Encoding.UTF8))
                    //    {
                    //        xmlSoapRequest.Load(readStream);
                    //        xmlPayload = xmlSoapRequest.SelectSingleNode("//Envelope/Body/GetRequisitionByDateResponse/").InnerText;
                    //    }
                    //}
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                    //DumpException(ex);
                    //this.ComponentMetaData.FireInformation(54, "", "Failed to deserialize: " + ex.Message + " Inner: " + ex.InnerException + " Source: " + ex.Source, "", 43, ref b);
                }
    
                return xmlResponse;
    
            }
    
            public static T DeserializeFromXml<T>(string xml)
            {
                T result;
    
                var ser = new XmlSerializer(typeof(T));
                using (var tr = new StringReader(xml))
                {
                    result = (T)ser.Deserialize(tr);
                }
                return result;
            }
        }
    
    
        [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Envelope
        {
            [XmlElement(ElementName = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
            public Body Body { get; set; }
            [XmlAttribute(AttributeName = "soap", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Soap { get; set; }
            [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Xsi { get; set; }
            [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Xsd { get; set; }
        }
    
    
    
    }
    

    【讨论】:

    • 还要确保 xml 从文件中的第一个字符开始,在左尖括号之前没有空格。
    • 我会从我在网页上所做的相同位置重新复制 xml,以确保没有差异。不知道还能尝试什么。
    • 上述代码中的信封类是你用的还是你自己的?上面的课程对我有用。
    • 看起来示例和实际的 xml 具有不同的命名空间。我假设我的代码适用于示例。所以在使用实际文件的时候必须要更改命名空间,使class和xml与命名空间保持一致。
    • 我们应该一次上一节课。现在我所关心的只是得到没有错误的响应。如果您有 www.w3 或只有 w3,这并不重要。另请查看您是否在 0,0 或 0,2 处出现错误,这是有区别的。我打算在周末尝试更多的东西。
    猜你喜欢
    • 1970-01-01
    • 2018-11-30
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    相关资源
    最近更新 更多