c# - Try-Catch 语句结束 While 循环读取 C# 中的 XML 文件

标签 c# while-loop try-catch switch-statement xmltextreader

我有一个 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 文件并选择“运行自定义工具”。)

enter image description here

  • 使用如下代码在运行时使用与您的示例相同的架构加载 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/

相关文章:

java - 当用户输入错误的输入时,我不知道如何重新启动循环

python - While 循环太早中断了。

java - 两种设计循环方式的区别

java - 可能的尝试/捕获和内存管理问题?

javascript - 是否有可能捕获因尝试连接到错误 url 而产生的异常?

c# - 使用 IQueryable 查找另一个坐标的半径内的点

c# - 无法找到请求的.Net Framework 数据提供程序。它可能没有安装。

c# - 必须将单个字符串传递给多个正则表达式模式,并且在匹配时我想要匹配的值

c# - 如何获取导致异常的方法的名称

c# - Web 请求和响应的 cookies 处理