在XML中存在无效的十六进制字符。
在XML中存在无效的十六进制字符。
我有一个包含无效十六进制字符的XML文件。我阅读了这个,这个和这个以及其他提供的链接,但都未能使其正常工作。
我正在使用XmlReader
- XmlDocument
,XDocument
和XmlTextReader
不是我的选择,因为XML文件的大小超过500GB,数量超过5亿。由于其“前向”方法以及不将所有XML细节加载到内存中,XMLReader是我最佳选择。也因为此原因,我无法重新创建或加载XML文件以替换无效字符。
以下是我正在使用的代码:
case XmlNodeType.Element: if (xmlReader.Name.Equals("ROW")) { DataRow dataRow = xmlDataTable.NewRow(); XmlReader row = XmlReader.Create(xmlReader.ReadSubtree(), new XmlReaderSettings { CheckCharacters = false , ValidationType = ValidationType.None }); // 迭代ROW内的元素 // 这些是列项目 if (row != null) { while (row.Read()) { if (row.IsStartElement()) { if (!row.Name.Equals("ROW")) { string columnName = row.Name; //row = XmlReader.Create(CleanInvalidXmlChars(row.ReadInnerXml())); row.Read(); string value = CleanInvalidXmlChars(row.Value.ToString()); // 其他逻辑...
异常发生在row.Read();
语句上。以下是我正在读取的示例XML文件:
|
828 GJ102 E 815412 0 0 0 0 A 0
目前,我在使其正常工作方面遇到了困难。
编辑:
示例XML文件是导致我的代码出错的记录。我从记事本中将其复制并粘贴在这里,但它不显示无效字符。以下是在记事本中的外观图像:
我如何创建xmlReader
对象只是这个简单的语句:
using (xmlReader = XmlReader.Create(filePath, new XmlReaderSettings { CheckCharacters = false }))
问题:在XML中出现无效的十六进制字符。
原因:不清楚为什么将CheckCharacters = false
设置为false不能解决问题,更好的解决方法是一开始就以清洁的方式获取数据。但是,可以通过在TextReader
中用替换字符替换每个无效字符来解决这个问题。
解决方法:
using System; using System.IO; using System.Xml; class Test { static void Main() { var text = "<foo>\0</foo>"; var reader = XmlReader.Create( new XmlReplacingReader(new StringReader(text), ' ')); while (reader.Read()) { Console.WriteLine(reader.NodeType); } } } public sealed class XmlReplacingReader : TextReader { private readonly TextReader original; private readonly char replacementChar; public XmlReplacingReader(TextReader original, char replacementChar) { this.original = original; this.replacementChar = replacementChar; } override public int Peek() { int ret = original.Peek(); return MaybeReplace(ret); } override public int Read() { int ret = original.Read(); return MaybeReplace(ret); } override public int Read(char[] buffer, int index, int count) { int ret = original.Read(buffer, index, count); for (int i = 0; i < ret; i++) { buffer[i + index] = MaybeReplace(buffer[i + index]); } return ret; } protected override void Dispose(bool disposing) { if (disposing) { original.Dispose(); } } public override void Close() { original.Close(); } private int MaybeReplace(int x) { return x < 0 ? x : MaybeReplace((char) x); } private char MaybeReplace(char c) { return (c >= ' ' || c == '\r' || c == '\n' || c == '\t') ? c : replacementChar; } }
这依赖于你能够为文件创建一个TextReader
,当然,如果你知道编码,可以使用File.OpenText
来做到这一点。如果需要处理其他编码,可能需要一个更聪明的解决方案,但这应该能帮助你入门。
请注意,这种方法替换了无效字符。如果你想删除它们,这将变得更困难,而且可能效率更低,因为批量Read
方法需要找出是否需要删除字符,执行删除操作,然后返回一个不同的值。代码将会更加复杂 - 希望你不需要它。
是的,我也在想为什么在这种情况下CheckCharacters
不起作用。我已经在许多其他情况下测试过它,它的功能是正确的,但现在我甚至不知道我做错了什么。我已经看了你的代码片段一段时间了,将尝试实现它并更新任何信息。