我有一个用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>();
...where 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个文档元素,但有很多):
<?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语句有其自身的复杂性,但我认为它工作得很好;失败的是LOAD。我已经研究了XDocument Load的各种构造函数,并研究了抛出此异常的其他一些问题,但我对如何防止这种情况感到困惑。
最后,在加载失败的文件中的52327行的位置126处,看起来52327行上的数据不应该引起问题(最后一个字符在位置103!
<FILE filename="e:\S2Out\B0000004\Pet Tab\D003710954.0001.pdf" outputpath="e:\S2Out\B0000004\Pet Tab"/>
发布于 2011-11-26 10:34:58
为了控制编码(一旦您知道它是什么),您可以使用接受Stream
的Load
方法覆盖来加载文件。
然后,您可以在构造函数中指定适当的Encoding
,针对您的文件创建新的StreamReader
。
例如,要使用西欧编码打开文件,请替换问题中的以下代码行:
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中找到。
发布于 2011-11-26 11:07:56
不确定这是否是您的情况,但这可能与给定编码的无效字节序列有关。示例:http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences。
尝试在加载时从文件中筛选无效序列。
发布于 2011-11-26 10:36:50
因为一旦遇到未编码的字符,XmlDocument就会加载整个过程,因此会中止整个过程。如果您想处理您能处理的内容并跳过/记录duff位,请查看XmlTextReader。从文件流加载的XmlTextReader将一次加载一个节点,因此它使用的内存也会少得多。您甚至可以变得更聪明,将事情拆分并并行化处理。
当我有这个的时候,它就像里面的重音字符:重音,尖音,变音,等等。
我没有任何自动化的过程,所以通常我只是在Visual Studio中加载文件,并将坏人编辑出来,直到没有曲折留下为止。不过,这个理论是合理的。
https://stackoverflow.com/questions/8275825
复制相似问题