C# 匹配xml时如何忽略值是否为NULL

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>

我有一个匹配XML文件的方法。两个XML都有相同的ClientRefNr。但我试图从两者中获取所有信息,并将其与一个XML进行匹配。那很好。但有时,Doc1有一些Doc2中不存在的ID(NULL)。这就是我需要跳过去继续的原因

XML1:

 <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