输入字符串格式不正确错误,但仍然能够从 LINQ 获取解析值到 XML 查询
Input string was not in a correct format error, but still able to get parsed value from LINQ to XML query
我有一个 xml 文件,我可以从中从某些节点获取 ID
s。节点具有以下结构:
<Bistot ID="1223"/>
<Compressed_Bistot ID="28388"/>
<Compressed_Monoclinic_Bistot ID="28389"/>
...
它们在我的 xml 文件中也处于不同的级别(它太大了,无法在此处一一列出)。
为了做到这一点,我使用了一个执行 LINQ 查询的函数:
public String GetItemName(uint id)
{
IEnumerable<String> names = _xmlFile.Descendants()
.Where(x => x.Attributes().Any(a => a.Name.LocalName == "ID") && uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value) == id)
.Select(t => t.Name.LocalName);
return names.ElementAt(0);
}
在这种形式中,如果我提供的 id
存在并且 names
变量实际上有一个条目,它就可以很好地工作。如果没有,它会在 return names.ElementAt(0);
处引发异常,因为在索引 0
处没有元素。此时,在调试模式下,如果我去检查变量 names
,我确实看到它提到了 Input string was not in a correct format
,但是 raised 和函数没有错误returns name
关联到 id
。
我还尝试了以下形式,以消除如果 LINQ 请求在 xml 文件中找不到任何关联名称时发生的异常:
public String GetItemName(uint id)
{
IEnumerable<String> names = _xmlFile.Descendants()
.Where(x => x.Attributes().Any(a => a.Name.LocalName == "ID") && uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value) == id)
.Select(t => t.Name.LocalName);
if (names.Count() != 0) // Error raised here
{
return names.ElementAt(0);
}
else
{
return "";
}
}
这就是我的问题所在,因为在这种情况下,当我调用 names.Count()
时,会引发 Input string was not in a correct format
(FormatException
类型)错误,然后我的应用程序不会continue/complete.
我也曾尝试在我的 LINQ 查询结束时调用 .ToList()
,因为我收到一条警告,告诉我这样做。但在这种情况下,Input string was not in a correct format
错误是在我的 LINQ 查询中直接引发的,而不是在 names.Count()
调用中引发的。
我确实理解这个错误的性质,当我在 LINQ 查询中调用 uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value)
时,有些东西没有得到正确的解析,但我不明白为什么有两个原因:
我手动检查过 xml 文件中 ID
属性中的每个值都是真实的 uint
(只有数字,没有空格等)。
当不使用 names.Count()
或 .ToList()
时,虽然当我查看变量时确实提到了调试模式下的错误,但与 [=15= 关联的名称] 仍然找到并且函数 returns 它正确。
为什么我的 uint.Parse(...)
给我带来麻烦?
问题是,当您使用 ElementAt(0)
时,它只需要找到第一个元素 - 所以如果后面有一个 ID
元素具有无效值(我确定有), 你不会击中它。当您调用 Count()
或 ToList()
时,它会遍历查询的 整个 ,从而导致问题。
事实上,您的代码非常低效,需要多次评估 - 最好写成:
public String GetItemName(uint id)
{
IEnumerable<String> names = ...; // Query as before
return names.FirstOrDefault() ?? "";
}
我还建议使用 LINQ 提供的显式转换 XML 而不是手动调用 uint.Parse
:
IEnumerable<String> names = _xmlFile.Descendants()
.Where(x => (uint?) x.Attributes()
.Where(a => a.Name.LocalName == "ID")
.FirstOrDefault() == id)
.Select(t => t.Name.LocalName);
在这里我们找到第一个 ID
属性,将其转换为 uint?
(如果没有这样的属性则给出 null
),然后将其与 id
进行比较.
我有一个 xml 文件,我可以从中从某些节点获取 ID
s。节点具有以下结构:
<Bistot ID="1223"/>
<Compressed_Bistot ID="28388"/>
<Compressed_Monoclinic_Bistot ID="28389"/>
...
它们在我的 xml 文件中也处于不同的级别(它太大了,无法在此处一一列出)。
为了做到这一点,我使用了一个执行 LINQ 查询的函数:
public String GetItemName(uint id)
{
IEnumerable<String> names = _xmlFile.Descendants()
.Where(x => x.Attributes().Any(a => a.Name.LocalName == "ID") && uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value) == id)
.Select(t => t.Name.LocalName);
return names.ElementAt(0);
}
在这种形式中,如果我提供的 id
存在并且 names
变量实际上有一个条目,它就可以很好地工作。如果没有,它会在 return names.ElementAt(0);
处引发异常,因为在索引 0
处没有元素。此时,在调试模式下,如果我去检查变量 names
,我确实看到它提到了 Input string was not in a correct format
,但是 raised 和函数没有错误returns name
关联到 id
。
我还尝试了以下形式,以消除如果 LINQ 请求在 xml 文件中找不到任何关联名称时发生的异常:
public String GetItemName(uint id)
{
IEnumerable<String> names = _xmlFile.Descendants()
.Where(x => x.Attributes().Any(a => a.Name.LocalName == "ID") && uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value) == id)
.Select(t => t.Name.LocalName);
if (names.Count() != 0) // Error raised here
{
return names.ElementAt(0);
}
else
{
return "";
}
}
这就是我的问题所在,因为在这种情况下,当我调用 names.Count()
时,会引发 Input string was not in a correct format
(FormatException
类型)错误,然后我的应用程序不会continue/complete.
我也曾尝试在我的 LINQ 查询结束时调用 .ToList()
,因为我收到一条警告,告诉我这样做。但在这种情况下,Input string was not in a correct format
错误是在我的 LINQ 查询中直接引发的,而不是在 names.Count()
调用中引发的。
我确实理解这个错误的性质,当我在 LINQ 查询中调用 uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value)
时,有些东西没有得到正确的解析,但我不明白为什么有两个原因:
我手动检查过 xml 文件中
ID
属性中的每个值都是真实的uint
(只有数字,没有空格等)。当不使用
names.Count()
或.ToList()
时,虽然当我查看变量时确实提到了调试模式下的错误,但与 [=15= 关联的名称] 仍然找到并且函数 returns 它正确。
为什么我的 uint.Parse(...)
给我带来麻烦?
问题是,当您使用 ElementAt(0)
时,它只需要找到第一个元素 - 所以如果后面有一个 ID
元素具有无效值(我确定有), 你不会击中它。当您调用 Count()
或 ToList()
时,它会遍历查询的 整个 ,从而导致问题。
事实上,您的代码非常低效,需要多次评估 - 最好写成:
public String GetItemName(uint id)
{
IEnumerable<String> names = ...; // Query as before
return names.FirstOrDefault() ?? "";
}
我还建议使用 LINQ 提供的显式转换 XML 而不是手动调用 uint.Parse
:
IEnumerable<String> names = _xmlFile.Descendants()
.Where(x => (uint?) x.Attributes()
.Where(a => a.Name.LocalName == "ID")
.FirstOrDefault() == id)
.Select(t => t.Name.LocalName);
在这里我们找到第一个 ID
属性,将其转换为 uint?
(如果没有这样的属性则给出 null
),然后将其与 id
进行比较.