我无法让我的程序正确读取这个XML文件,它还需要写入它但尚未写入。请注意,这只是代码的一小部分
XmlDocument InstalledList = new XmlDocument();
InstalledList.Load(AppsInstalledFileNamePath);
//Sets the PackageNode to the correct part of the XmlDocument
XmlNodeList PackagesNode = InstalledList.GetElementsByTagName("installed");
foreach (XmlNode InstalledListNodes in PackagesNode)
{
//If the title is the same as what the user typed, continue on
if (InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true)
{
BatchProcessFileName = InstalledListNodes.Attributes["uninstallername"].InnerText;
Console.WriteLine("Filename OK");
我也把try语句拿出来,所以我不必添加catch
下面是它试图读取(后来写入)的XML文件
<?xml version="1.0" encoding="utf-8" ?>
<packages>
<installed>
<sampleapp title="sampleapp" id="00001" uninstallername="sampleapp.bat" installdate="11/15/09"></sampleapp>
<sampleapp2 title="sampleapp2" id="00002" uninstallername="sampleapp2.bat" installdate="11/16/09"></sampleapp2>
</installed>
<uninstalled>
</uninstalled>
</packages>
代码运行,但在
处有一个NullReference异常InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true
答案 0 :(得分:1)
嗯,我可以在以下行看到三个不同的失败点:
InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true
^--Null? ^-- Null? ^--Null?
我会将这个长链分解为更多离散元素,并在每个元素上检查null以缩小它:
if (InstalledListNodes != null)
{
var attribute = InstalledListNodes.Attributes["title"];
if (attribute != null)
{
if (attribute.InnerText.Equals(packagename) == true)
{
// ...
}
}
}
也就是说,在检索属性值时,我会使用 .Value 属性而不是 .InnerText 属性。从元素打开和关闭标记中检索文本内容时,应使用InnerText。
答案 1 :(得分:1)
似乎是一个小错字;
请注意,您写了Attributes["unintallername"]
,它应该是Attributes["uninstallername"]
答案 2 :(得分:1)
仅供参考,与普遍认为相反: InnerText
对于属性或元素1}}永远不会null
。这意味着,您根本不必检查InnerText
是否为空。空元素和属性的InnerText
空字符串:
XmlDocument docx = new XmlDocument();
docx.LoadXml("<root test='' />");
Debug.WriteLine("Empty: " + docx.FirstChild.InnerText);
Debug.WriteLine("Empty: " + docx.FirstChild.Attributes["test"].InnerText);
但是,如果属性本身不存在,则属性本身可以返回null
。正如jrista已经指出的那样,除非你真的必须使用InnerText
,否则它是无用的。坚持Value
而不是。{/ p>
许多人已对此发表评论。你有:
XmlNodeList PackagesNode = InstalledList.GetElementsByTagName("installed");
foreach (XmlNode InstalledListNodes in PackagesNode)
{
if (InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true)
....
使用您显示的XML,这将无法工作,因为<installed>
没有属性。尝试:
XmlNodeList PackagesNode = InstalledList.GetElementsByTagName("installed");
foreach (XmlNode InstalledListNodes in PackagesNode)
{
XmlNode someNode = InstalledListNodes.FirstChild;
if (someNode.Attributes["title"].InnerText.Equals(packagename) == true)
....
它不会(还)提供你想要的效果,但是someNode
现在指向一个实际拥有title属性的节点,向你展示如何摆脱这个错误。
删除错误后,我想以另一种方式向您展示:XPath。使用XPath,这种类型的任务实际上要容易得多。以下是我对你的问题的看法(未经测试):
// assuming <packages> is root:
XmlNodeList applicationNodes = InstalledList.SelectNodes("/packages/installed/*");
foreach (XmlNode applicationNode in applicationNodes)
{
if (applicationNode.Attributes["title"].Value.Equals(packagename) == true)
{
.... etc
重要提示:其他人所说的关于检查节点步骤返回值的内容仍然非常重要。如果您的输入数据不存在,那么您的代码将会很难实现。只需始终检查每一步,或使用更多XPath,让您的生活更轻松。
更新: 仅供参考
更新:添加了解决方案
更新:添加了替代解决方案(无法抗拒)