Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何防止System.Xml.XmlException:给定编码中的无效字符_C#_Xml_Linq To Xml - Fatal编程技术网

C# 如何防止System.Xml.XmlException:给定编码中的无效字符

C# 如何防止System.Xml.XmlException:给定编码中的无效字符,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我有一个用C#编写的Windows桌面应用程序,它循环遍历存储在磁盘上的一堆XML文件,这些文件是由第三方程序创建的。以下语句后面的LINQ代码成功加载和处理了大部分文件: XDocument xmlDoc = XDocument.Load(inFileName); List<DocMetaData> docList = (from d in xmlDoc.Descendants("DOCUMENT") select new DocMetaData

我有一个用C#编写的Windows桌面应用程序,它循环遍历存储在磁盘上的一堆XML文件,这些文件是由第三方程序创建的。以下语句后面的LINQ代码成功加载和处理了大部分文件:

XDocument xmlDoc = XDocument.Load(inFileName);
List<DocMetaData> docList =
      (from d in xmlDoc.Descendants("DOCUMENT")
       select new DocMetaData
       {
      File = d.Element("FILE").SafeGetAttributeValue("filename")
         ,
      Folder = d.Element("FOLDER").SafeGetAttributeValue("name")
         ,
      ItemID = d.Elements("INDEX")
          .Where(i => (string)i.Attribute("name") == "Item ID(idmId)")
          .Select(i => (string)i.Attribute("value"))
          .FirstOrDefault()
         ,
      Comment = d.Elements("INDEX")
          .Where(i => (string)i.Attribute("name") == "Comment(idmComment)")
          .Select(i => (string)i.Attribute("value"))
          .FirstOrDefault()
         ,
      Title = d.Elements("INDEX")
          .Where(i => (string)i.Attribute("name") == "Title(idmName)")
          .Select(i => (string)i.Attribute("value"))
          .FirstOrDefault()
         ,
      DocClass = d.Elements("INDEX")
          .Where(i => (string)i.Attribute("name") == "Document Class(idmDocType)")
          .Select(i => (string)i.Attribute("value"))
          .FirstOrDefault()
       }
      ).ToList<DocMetaData>();
但有一些文件会导致以下问题:

System.Xml.XmlException: Invalid character in the given encoding. Line 52327, position 126.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.InvalidCharRecovery(Int32& bytesCount, Int32& charsCount)
at System.Xml.XmlTextReaderImpl.GetChars(Int32 maxCharsCount)
at System.Xml.XmlTextReaderImpl.ReadData()
at System.Xml.XmlTextReaderImpl.ParseAttributeValueSlow(Int32 curPos, Char quoteChar, NodeData attr)
at System.Xml.XmlTextReaderImpl.ParseAttributes()
at System.Xml.XmlTextReaderImpl.ParseElement()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r)
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o)
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Load(String uri, LoadOptions options)
at System.Xml.Linq.XDocument.Load(String uri)
at CBMI.WinFormsUI.GridForm.processFile(StreamWriter oWriter, String inFileName, Int32 XMLfileNumber) in C:\ProjectsVS2010\CBMI.LatitudePostConverter\CBMI.LatitudePostConverter\CBMI.WinFormsUI\GridForm.cs:line 147
at CBMI.WinFormsUI.GridForm.btnProcess_Click(Object sender, EventArgs e) in C:\ProjectsVS2010\CBMI.LatitudePostConverter\CBMI.LatitudePostConverter\CBMI.WinFormsUI\GridForm.cs:line 105
XML文件如下所示(此示例仅显示2个文档元素,但有很多):


LINQ语句有其自身的复杂性,但我认为它可以正常工作;失败的是负载。我已经研究了XDocument Load的各种构造函数,并研究了引发此异常的其他一些问题,但我对如何防止此问题感到困惑

最后,在加载失败的文件的第52327行位置126处,第52327行上的数据似乎不应该导致问题(最后一个字符位于位置103


为了控制编码(一旦您知道它是什么),您可以使用接受
流的
load
方法重载文件

然后,您可以针对文件创建一个新的
StreamReader
,在构造函数中指定适当的
编码

例如,要使用西欧编码打开文件,请替换问题中的以下代码行:

XDocument xmlDoc = XDocument.Load(inFileName);
使用此代码:

XDocument xmlDoc = null;

using (StreamReader oReader = new StreamReader(inFileName, Encoding.GetEncoding("ISO-8859-1"))) {
    xmlDoc = XDocument.Load(oReader);
}

支持的编码列表可以在中找到。

,因为XmlDocument在遇到未编码字符时会加载整个内容,并中止整个过程。 如果您想处理可以处理的内容并跳过/记录无用位,请查看XmlTextReader。 从文件流加载的XmlTextReader将一次加载一个节点,因此它也将使用更少的内存。您甚至可以更聪明地将其拆分并并行处理

当我有这个的时候,里面有一些像重音符号的东西:坟墓、尖塔、乌姆劳特等等


我没有任何自动过程,所以通常我只是在Visual Studio中加载文件并编辑坏家伙,直到没有任何扭曲。不过理论是正确的。

引用的文件包含一个对文件名有效的字符,但在XML属性中无效。您有几个选项

  • 您可以更改文件名并重新运行第三方脚本
  • 您可以与供应商合作,提供一个补丁,安全地对违规字符进行编码
  • 您可以预先验证XML文档,并在处理之前删除有问题的条目

  • 不确定这是否是您的情况,但这可能与给定编码的无效字节序列有关。示例:


    加载时尝试从文件中筛选无效序列。

    是否可以包括失败文件的第52327行,以便我们可以查看导致异常的内容?只是添加了它。对我来说没有意义。请发布实际会导致问题的XML。下一行或上一行如何?他们是否有相应的NUB此外,您可以尝试在一个编辑器中打开(如果您还没有),该编辑器至少可以显示无效字符的占位符(即NoteTab Pro,我建议这样做是因为它是我唯一知道的)。大多数流行的web浏览器将验证您的XML,并向您显示找到无效内容的确切位置。选项2是主要选项。编写用于生成XML文档的软件的供应商应该提供有效的XML。他们的错误可能不仅会影响您,还会影响其他客户。谢谢。我在其他地方看到过这一讨论。我的LINQ code(我刚刚通过编辑将其添加到该线程的顶部)取决于XDocument对象的.subjections方法。在我阅读您的建议时,我必须切换到使用StreamReader对象执行等效操作。这是正确的,还是我误解了您指向我的位置?抱歉,我想您误解了:您只需要替换当前加载(inFileName)在我的回答中使用代码声明。这只是将文件加载到文档中的另一种方式,但允许您指定编码,以便正确读取文件。非常感谢。在您出色的说明后,我现在理解了。非常好。