C# 匹配xml时如何忽略值是否为NULL
我有一个匹配XML文件的方法。两个XML都有相同的ClientRefNr。但我试图从两者中获取所有信息,并将其与一个XML进行匹配。那很好。但有时,Doc1有一些Doc2中不存在的ID(NULL)。这就是我需要跳过去继续的原因 XML1:C# 匹配xml时如何忽略值是否为NULL,c#,xml,C#,Xml,我有一个匹配XML文件的方法。两个XML都有相同的ClientRefNr。但我试图从两者中获取所有信息,并将其与一个XML进行匹配。那很好。但有时,Doc1有一些Doc2中不存在的ID(NULL)。这就是我需要跳过去继续的原因 XML1: <Table1> <Id>1581016</ClientRefNr> <Id>12</Id> <Value>All commentary</Value>
<Table1>
<Id>1581016</ClientRefNr>
<Id>12</Id>
<Value>All commentary</Value>
</Table1>
<Table1>
<ClientRefNr>754030</ClientRefNr>
<Id>17</Id>
<Value>All commentary</Value>
</Table1>
<Table1>
<ClientRefNr>1581016</ClientRefNr>
<Id>12</Id>
<Name>All commentary</Name>
</Table1>
<Table1>
<ClientRefNr>75885</ClientRefNr>
<Id>11</Id>
<Name>Martin</Name>
</Table1>
有什么想法吗?如果Doc2中不存在ClientRefNr,如何忽略它?检查Where函数是否返回了任何元素如何? 更改: 如果您的C#版本足够高(即不为非常旧的.NET版本构建),另一个解决方案是使用
?。
-运算符,该运算符在左侧不为null时执行函数,如果左侧为null
,则返回null本身:
doc2Elements.Where(x=>x.ToString().IndexOf(ClientRefNr)>-1.FirstOrDefault()?.Elements()?.ToList()代码>
当FirstOrDefault
返回null
时,doc2Childs
将为null
如果您希望在发生这种情况时它是一个空列表,您可以这样做
doc2Elements.Where(x=>x.ToString().IndexOf(ClientRefNr)>-1.FirstOrDefault()?.Elements().ToList()??新列表()代码>
这将导致在左侧为null
总而言之:a??b
是a==null的缩写?b:a
而a?.b
是a==null的缩写?null:a.b
有两种解决方案,具体取决于在某个XML文件中遇到null值时要执行的操作
忽略它,继续前进
承认并
- 继续
- 跳过
- 中断
1:
List doc2Childs=doc2Elements.Where(x=>x.ToString().IndexOf(ClientRefNr)>-1.FirstOrDefault()?.Elements()?.ToList();
看起来和你做的一样,对吧?有一点不同,我用的是
仅当操作数的计算结果为非空时,才将成员访问、、、或元素访问、[]操作应用于其操作数;否则,它将返回null
这意味着您的列表doc2Childs
在此操作后可能为空,也可能不为空,因此请注意后续的错误
2:
var doc2TempResult=doc2Elements.Where(x=>x.ToString().IndexOf(ClientRefNr)>-1.FirstOrDefault();
//除了继续,你还可以休息,或者做任何你想/需要的事情
if(doc2TempResult为null | |!(doc2TempResult.Elements()为IEnumerable doc2Elements))
继续;
var doc2Childs=doc2Elements.ToList()
这个函数显式地检查null,它还检查doc2TempResult
的元素是否是IEnumerable
(由elements()
方法指定)。如果不是,则与temp结果为null时相同(如果希望以不同方式处理这些情况,可以将其拆分为2个If检查)。然后,它通过调用ToList()
将IEnumerable转换为一个列表,就像您以前所做的那样这是因为您正在使用,如果找不到项,它将返回null。然后直接调用.Elements()。您可以将其拆分,以便调用FirstOrDefault
,将该结果分配给一个变量,然后检查它是否为null。或者,如果没有其他人关心它是否为null,请使用null条件运算符。没有问题,我目前正在键入一个答案,进一步详细解释这两种解决方案
public XDocument MatchClientCommWithLZ(XDocument ClientCommXML, XDocument doc2)
{
XDocument result = new XDocument();
List<XElement> doc1Elements = ClientCommXML.Root.Elements().ToList();
List<XElement> doc2Elements = doc2.Root.Elements().ToList();
XElement accountElement = new XElement("ClientRefNr");
result = new XDocument(accountElement);
for (int i = 0; i < doc1Elements.Count(); i++)
{
XmlDocument subDoc = new XmlDocument();
subDoc.LoadXml(doc1Elements[i].ToString());
string tableName = subDoc.FirstChild.Name;
string ClientRefNr = doc1Elements[i].Elements().Where(x => x.Name == "ClientRefNr").FirstOrDefault().Value;
List<XElement> doc1Childs = doc1Elements[i].Elements().ToList();
List<XElement> doc2Childs = doc2Elements.Where(x => x.ToString().IndexOf(ClientRefNr) > -1).FirstOrDefault().Elements().ToList();
XElement tblElement = new XElement(tableName);
tblElement.Add(new XElement("Id", GetClientValue(doc1Childs, doc2Childs, "Id")));
tblElement.Add(new XElement("ClientRefNr", GetClientValue(doc1Childs, doc2Childs, "ClientRefNr")));
tblElement.Add(new XElement("Name", GetClientValue(doc1Childs, doc2Childs, "Name")));
tblElement.Add(new XElement("Value", GetClientValue(doc1Childs, doc2Childs, "Value")));
accountElement.Add(tblElement);
}
return result;
}
An unhandled exception of type 'System.NullReferenceException' because this is NULL
List<XElement> doc2Childs = doc2Elements.Where(x => x.ToString().IndexOf(ClientRefNr) > -1).FirstOrDefault().Elements().ToList();
List<XElement> doc2Childs = doc2Elements.Where(x => x.ToString().IndexOf(ClientRefNr) > -1).FirstOrDefault().Elements().ToList();
var tempResult = doc2Elements.Where(x => x.ToString().IndexOf(ClientRefNr) > -1).FirstOrDefault();
if(tempResult==null || tempResult.Elements() == null)
continue;
//... rest of the code