我有一个 while 循环遍历 XML 文件,对于其中一个节点“url”,其中有时包含无效值。我围绕它放置了一个 try-catch 语句来捕获任何无效值。问题是,每当抓取一个无效值时,while 循环就会被终止,程序会在该循环之外继续运行。如果找到无效值,我需要 while 循环继续读取 XML 文件的其余部分。
这是我的代码:
XmlTextReader reader = new XmlTextReader(fileName);
int tempInt;
while (reader.Read())
{
switch (reader.Name)
{
case "url":
try
{
reader.Read();
if (!reader.Value.Equals("\r\n"))
{
urlList.Add(reader.Value);
}
}
catch
{
invalidUrls.Add(urlList.Count);
}
break;
}
}
我选择不包含 switch 语句的其余部分,因为它不相关。这是我的 XML 示例:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<visited_links_list>
<item>
<url>http://www.grcc.edu/error.cfm</url>
<title>Grand Rapids Community College</title>
<hits>20</hits>
<modified_date>10/16/2012 12:22:37 PM</modified_date>
<expiration_date>11/11/2012 12:22:38 PM</expiration_date>
<user_name>testuser</user_name>
<subfolder></subfolder>
<low_folder>No</low_folder>
<file_position>834816</file_position>
</item>
</visited_links_list>
我在整个代码中遇到的异常类似于以下内容:
“'',十六进制值0x05,是无效字符。第3887行,位置13。”
最佳答案
观察:
您为每个条目调用 reader.Read()
两次。一次在 while()
中,一次在 case
中。你真的要跳过记录吗?如果源 XML 中的条目数量为奇数,这将导致异常(因为 reader.Read()
将 XML 流中的指针前进到下一个项目) ,但该异常不会被捕获,因为它发生在您的try...catch
之外。
除此之外:
reader.Read(); /// might return false, but no exception, so keep going...
if (!reader.Value.Equals("\r\n")) /// BOOM if the previous line returned false, which you ignored
{
urlList.Add(reader.Value);
}
/// reader is now in unpredictable state
编辑
冒着写长篇答案的风险...
你收到的错误
“'',十六进制值0x05,是无效字符。第3887行,位置13。”
表示您的源 XML 格式不正确,并且以某种方式在指定位置以 ^E
(ASCII 0x05) 结尾。我会看看那条线。如果您从供应商或服务处获得此文件,则应该让他们修复代码。更正该内容以及您的 XML 中的任何其他格式错误的内容,应该可以更正您所看到的问题。
修复后,您的原始代码应该可以工作。但是,为此使用 XmlTextReader
并不是最可靠的解决方案,并且涉及构建一些 Visual Studio 会很乐意为您生成的代码:
在VS2012中(我没有再装VS2010,不过应该是一样的过程):
将 XML 示例添加到您的解决方案
在该文件的属性中,将 CustomTool 设置为“MSDataSetGenerator”(不带引号)
IDE 应生成一个 .designer.cs 文件,其中包含一个可序列化的类,该类具有用于 XML 中每个项目的字段。 (如果没有,请在解决方案资源管理器中右键单击 XML 文件并选择“运行自定义工具”。)
使用如下代码在运行时使用与您的示例相同的架构加载 XML:
/// make sure the XML doesn't have errors, such as non-printable characters private static bool IsXmlMalformed(string fileName) { var reader = new XmlTextReader(fileName); var result = false; try { while (reader.Read()) ; } catch (Exception e) { result = true; } return result; } /// Process the XML using deserializer and VS-generated XML proxy classes private static void ParseVisitedLinksListXml(string fileName, List<string> urlList, List<int> invalidUrls) { if (IsXmlMalformed(fileName)) throw new Exception("XML is not well-formed."); using (var textReader = new XmlTextReader(fileName)) { var serializer = new XmlSerializer(typeof(visited_links_list)); if (!serializer.CanDeserialize(textReader)) throw new Exception("Can't deserialize this XML. Make sure the XML schema is up to date."); var list = (visited_links_list)serializer.Deserialize(textReader); foreach (var item in list.item) { if (!string.IsNullOrEmpty(item.url) && !item.url.Contains(Environment.NewLine)) urlList.Add(item.url); else invalidUrls.Add(urlList.Count); } } }
您也可以使用 Windows SDK 附带的 XSD.exe 工具执行此操作。
关于c# - Try-Catch 语句结束 While 循环读取 C# 中的 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12923630/