C# 在使用XMLC文档时遇到问题#
我很难让我的程序正确读取这个XML文件,它也需要写入,但还没有。请注意,这只是代码的一小部分C# 在使用XMLC文档时遇到问题#,c#,xml,xmldocument,nullreferenceexception,C#,Xml,Xmldocument,Nullreferenceexception,我很难让我的程序正确读取这个XML文件,它也需要写入,但还没有。请注意,这只是代码的一小部分 XmlDocument InstalledList = new XmlDocument(); InstalledList.Load(AppsInstalledFileNamePath); //Sets the PackageNode to the correct part of the XmlDocument XmlNodeList PackagesNode = InstalledList.GetEl
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语句拿了出来,这样我就不必添加捕获
下面是它试图读取(以及稍后写入)的XML文件
那么,我可以在下面这行中看到三个不同的故障点:
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。似乎是一个小错误
请注意,您编写了
属性[“uninstallername”]
,它应该是属性[“unnstallerName”]
供参考,与流行的观点相反:InnerText
对于属性或元素来说永远不会为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);
对于您展示的XML,这将永远不会起作用,因为
没有属性。尝试:
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,这类任务实际上要容易得多。以下是我对您的问题的看法(未经测试):
//假设是根目录:
XmlNodeList applicationNodes=InstalledList.SelectNodes(“/packages/installed/*”);
foreach(applicationNodes中的XmlNode applicationNode)
{
if(applicationNode.Attributes[“title”].Value.Equals(packagename)==true)
{
等
重要提示:其他人所说的关于检查节点步骤返回值的内容仍然非常重要。如果没有任何输入数据,您的代码将很难失败。只需始终检查每个步骤,或使用更多XPath以使您的生活更轻松
更新:FYI更新:添加了解决方案
<强>更新:< /强>附加替代解决方案(不可抗拒)未成年人:考虑将奇异对象保持变量改为其单数英文名称,反之亦然:<代码> FURACH(XmlNode InstalledListNode在PACKAGESTNORE节点中)我编辑了您的问题,删除了与XML处理无关的部分,希望您不介意。不客气!PS:您也可以使用XPath一次性选择packagename,无需手动循环:
SelectNodes(String.Format(“packages/installed/*[title='{0}'],packagename))
。省去了很多麻烦!谢谢你的否决票,但想详细说明原因吗?我很乐意更新我的答案以更正任何错误。我不小心又一次打了起来lol对不起,它不会让我再打一次+1完全同意空测试,但是…无论是值
还是InnerText
对于属性,都不会为空尤特。
XmlDocument docx = new XmlDocument();
docx.LoadXml("<root test='' />");
Debug.WriteLine("Empty: " + docx.FirstChild.InnerText);
Debug.WriteLine("Empty: " + docx.FirstChild.Attributes["test"].InnerText);
XmlNodeList PackagesNode = InstalledList.GetElementsByTagName("installed");
foreach (XmlNode InstalledListNodes in PackagesNode)
{
if (InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true)
....
XmlNodeList PackagesNode = InstalledList.GetElementsByTagName("installed");
foreach (XmlNode InstalledListNodes in PackagesNode)
{
XmlNode someNode = InstalledListNodes.FirstChild;
if (someNode.Attributes["title"].InnerText.Equals(packagename) == true)
....
// assuming <packages> is root:
XmlNodeList applicationNodes = InstalledList.SelectNodes("/packages/installed/*");
foreach (XmlNode applicationNode in applicationNodes)
{
if (applicationNode.Attributes["title"].Value.Equals(packagename) == true)
{
.... etc