c# - 如何防止 System.Xml.XmlException : Invalid character in the given encoding

标签 c# xml linq-to-xml

我有一个用 C# 编写的 Windows 桌面应用程序,它循环访问存储在磁盘上并由第 3 方程序创建的一堆 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>();

...其中 inFileName 是完整路径和文件名,例如:

     Y:\S2Out\B0000004\Pet Tab\convert.B0000004.Pet Tab.xml

但是一些文件会导致这样的问题:

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 个 DOCUMENT 元素,但实际上有很多):

<?xml version="1.0" ?>
<DOCUMENTCOLLECTION>
   <DOCUMENT>
       <FILE filename="e:\S2Out\B0000005\General\D003712420.0001.pdf" outputpath="e:\S2Out\B0000005\General"/>
       <ANNOTATION filename=""/>
       <INDEX name="Comment(idmComment)" value=""/>
       <INDEX name="Document Class(idmDocType)" value="General"/>
       <INDEX name="Item ID(idmId)" value="003712420"/>
       <INDEX name="Original File Name(idmDocOriginalFile)" value="Matrix Aligning 603.24 Criteria to Petition Pages.pdf"/>
       <INDEX name="Title(idmName)" value="Matrix for 603.24"/>
       <FOLDER name="/Accreditation/PASBVE/2004-06"/>
   </DOCUMENT>
   <DOCUMENT>
       <FILE filename="e:\S2Out\B0000005\General\D003712442.0001.pdf" outputpath="e:\S2Out\B0000005\General"/>
       <ANNOTATION filename=""/>
       <INDEX name="Comment(idmComment)" value=""/>
       <INDEX name="Document Class(idmDocType)" value="General"/>
       <INDEX name="Item ID(idmId)" value="003712442"/>
       <INDEX name="Original File Name(idmDocOriginalFile)" value="Contacts at NDU.pdf"/>
       <INDEX name="Title(idmName)" value="Contacts at NDU"/>
       <FOLDER name="/Accreditation/NDU/2006-12/Self-Study"/>
   </DOCUMENT>

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

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

<FILE filename="e:\S2Out\B0000004\Pet Tab\D003710954.0001.pdf" outputpath="e:\S2Out\B0000004\Pet Tab"/>

最佳答案

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

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

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

XDocument xmlDoc = XDocument.Load(inFileName);

使用此代码:

XDocument xmlDoc = null;

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

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

关于c# - 如何防止 System.Xml.XmlException : Invalid character in the given encoding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8275825/

相关文章:

java - 使用 Java 连接多个 XML 文档

c# - Powershell 脚本在一台计算机上运行正常,但在另一台计算机上出错

c# - 在 JavaScript 中使用服务器端资源

c# - 如何使用 AutoMapper 将 IEnumerable 映射到列表

java - SAAJ:TextNode 中的 XML。报价未转义

c# - 从 XElement 中删除属性

c# - 计时器控制间隔

c# - 序列化到现有文件并删除声明

.net - AppendChild 和指定方法不支持异常

c# - 3 尝试使用 C# 删除 XML 节点