C# Try Catch语句在循环读取C中的XML文件时结束#
我有一个while循环遍历一个XML文件,对于其中一个节点“url”,其中有时存在无效值。我在这周围放了一个try-catch语句来捕获任何无效值。问题是,每当抓取一个无效值时,while循环被终止,程序继续在该循环之外运行。如果发现无效值,我需要while循环继续读取XML文件的其余部分 这是我的密码:C# Try Catch语句在循环读取C中的XML文件时结束#,c#,while-loop,try-catch,switch-statement,xmltextreader,C#,While Loop,Try Catch,Switch Statement,Xmltextreader,我有一个while循环遍历一个XML文件,对于其中一个节点“url”,其中有时存在无效值。我在这周围放了一个try-catch语句来捕获任何无效值。问题是,每当抓取一个无效值时,while循环被终止,程序继续在该循环之外运行。如果发现无效值,我需要while循环继续读取XML文件的其余部分 这是我的密码: XmlTextReader reader = new XmlTextReader(fileName); int tempInt; while
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>
http://www.grcc.edu/error.cfm
大急流社区学院
20
2012年10月16日下午12:22:37
2012年11月11日12:22:38下午
测试用户
不
834816
我在整个代码中遇到的异常与以下类似:
““”,十六进制值0x05,是无效字符。第3887行,位置13。”使用
我有一种感觉,抛出异常后,
reader
处于错误状态(作为reader.Read();
(在开关中,而不是while
)中的reader.Read()
很可能是发生异常的那一行。然后while
中的reader.Read()
不返回任何内容,它退出
我在一个控制台应用程序中做了一个简单的开关
,在其中捕获和异常,包含的循环继续进行
var s = "abcdefg";
foreach (var character in s)
{
switch (character)
{
case 'c':
try
{
throw new Exception("c sucks");
}
catch
{
// Swallow the exception and move on?
}
break;
default:
Console.WriteLine(character);
break;
}
}
如果您浏览代码,它是否会在捕获异常后在
的同时尝试运行中的reader.Read()
您正在为每个条目调用reader.Read()
两次。在while()
中调用一次,在案例中调用一次。您真的想跳过记录吗?如果源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);
}
}
}
///确保XML没有错误,例如不可打印的字符
私有静态bool isxmlmorformed(字符串文件名)
{
var reader=新的XmlTextReader(文件名);
var结果=假;
尝试
{
while(reader.Read());
}
捕获(例外e)
{
结果=真;
}
返回结果;
}
///使用反序列化器和VS生成的XML代理类处理XML
私有静态void ParseVisitedLinksListXml(字符串文件名、列表URL列表、列表无效URL)
{
if(isxmlmorformed(文件名))
抛出新异常(“XML格式不正确”);
使用(var textleader=newxmltextreader(文件名))
{
var serializer=新的XmlSerializer(typeof(已访问链接列表));
if(!serializer.CanDeserialize(textReader))
抛出新异常(“无法反序列化此XML。请确保XML架构是最新的。”);
var list=(已访问链接列表)序列化程序。反序列化(textReader);
foreach(list.item中的var项)
{
如果(!string.IsNullOrEmpty(item.url)和&!item.url.Contains(Environment.NewLine))
添加(item.url);
其他的
invalidURL.Add(urlist.Count);
}
}
}
您也可以使用Windows SDK附带的XSD.exe工具执行此操作。我假设您正在阅读有效的xml文档,如myFile.xml。我还假设“url”是您要获取的元素
将文档加载到XMLDocument类中,并使用该类遍历节点。这将消除错误字符,因为它将这些字符转换为正确的格式,如&将转换为amp;etc
下面的方法在给出您提供的示例时应该有效
//get the text of the file into a string
System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\test.xml");
String xmlText = sr.ReadToEnd();
sr.Close();
//Create a List of strings and call the method
List<String> urls = readXMLDoc(xmlText);
//check to see if we have a list
if (urls != null)
{
//do somthing
}
private List<String> readXMLDoc(String fileText)
{
//create a list of Strings to hold our Urls
List<String> urlList = new List<String>();
try
{
//create a XmlDocument Object
XmlDocument xDoc = new XmlDocument();
//load the text of the file into the XmlDocument Object
xDoc.LoadXml(fileText);
//Create a XmlNode object to hold the root node of the XmlDocument
XmlNode rootNode = null;
//get the root element in the xml document
for (int i = 0; i < xDoc.ChildNodes.Count; i++)
{
//check to see if it is the root element
if (xDoc.ChildNodes[i].Name == "visited_links_list")
{
//assign the root node
rootNode = xDoc.ChildNodes[i];
break;
}
}
//Loop through each of the child nodes of the root node
for (int j = 0; j < rootNode.ChildNodes.Count; j++)
{
//check for the item tag
if (rootNode.ChildNodes[j].Name == "item")
{
//assign the item node
XmlNode itemNode = rootNode.ChildNodes[j];
//loop through each if the item tag's elements
foreach (XmlNode subNode in itemNode.ChildNodes)
{
//check for the url tag
if (subNode.Name == "url")
{
//add the url string to the list
urlList.Add(subNode.InnerText);
}
}
}
}
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
return null;
}
//return the list
return urlList;
}
//将文件文本转换为字符串
System.IO.StreamReader sr=new System.IO.StreamReader(@“C:\test.xml”);
字符串xmlText=sr.ReadToEnd();
高级关闭();
//创建字符串列表并调用该方法
列表URL=readXMLDoc(xmlText);
//看看我们有没有名单
如果(URL!=null)
{
//干坏事
}
私有列表readXMLDoc(字符串文件文本)
{
//创建一个字符串列表来保存我们的URL
List urlList=新列表();
尝试
{
//克雷亚
//get the text of the file into a string
System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\test.xml");
String xmlText = sr.ReadToEnd();
sr.Close();
//Create a List of strings and call the method
List<String> urls = readXMLDoc(xmlText);
//check to see if we have a list
if (urls != null)
{
//do somthing
}
private List<String> readXMLDoc(String fileText)
{
//create a list of Strings to hold our Urls
List<String> urlList = new List<String>();
try
{
//create a XmlDocument Object
XmlDocument xDoc = new XmlDocument();
//load the text of the file into the XmlDocument Object
xDoc.LoadXml(fileText);
//Create a XmlNode object to hold the root node of the XmlDocument
XmlNode rootNode = null;
//get the root element in the xml document
for (int i = 0; i < xDoc.ChildNodes.Count; i++)
{
//check to see if it is the root element
if (xDoc.ChildNodes[i].Name == "visited_links_list")
{
//assign the root node
rootNode = xDoc.ChildNodes[i];
break;
}
}
//Loop through each of the child nodes of the root node
for (int j = 0; j < rootNode.ChildNodes.Count; j++)
{
//check for the item tag
if (rootNode.ChildNodes[j].Name == "item")
{
//assign the item node
XmlNode itemNode = rootNode.ChildNodes[j];
//loop through each if the item tag's elements
foreach (XmlNode subNode in itemNode.ChildNodes)
{
//check for the url tag
if (subNode.Name == "url")
{
//add the url string to the list
urlList.Add(subNode.InnerText);
}
}
}
}
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
return null;
}
//return the list
return urlList;
}