XML C# 如果多个子元素中的任何一个包含数组中的值,如何删除父元素

XML C# How to remove parent element if any of multiple child elements contains a value in an array

我有一个 XML 文件,我想将其与 XML 文件中不允许的数字数组进行匹配。如果任何子节点包含数组中的任何数字,我想删除父节点。

数组:

int [] excluded = new int[] { 112659, 112800, 113201}

我的 XML 文件如下所示:

<?xml version="1.0" encoding="Windows-1252" standalone="yes"?>
<file>
  <fakturor>
    <kund>
      <number>11354</number>
    </kund>
    <faktura>
      <number>112657</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
  <fakturor>
    <kund>
      <number>234</number>
    </kund>
    <faktura>
      <number>112658</number>
    </faktura>
        <faktura>
      <number>112659</number>
    </faktura>
        <faktura>
      <number>112660</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
    <fakturor>
    <kund>
      <number>24202</number>
    </kund>
    <faktura>
      <number>112661</number>
    </faktura>
        <faktura>
      <number>112662</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
</file>

在示例中,我想删除父元素 "fakturor",其中有一个子 faktura,编号为 112659。

我一直在编写一些 C# 代码,这就是我目前的进度。

var xmlDoc = XDocument.Load(file.FullName);

        List<string> excluded = new List<string> { "112659", "112800", "113201" };

        var allFakturor = xDoc.Descendants("fakturor");

        foreach (var parentFaktura in allFakturor)
        {
            var hasChildToBeExcluded = parentFaktura.Elements("faktura").Where(t => excluded.Contains(t.Element("number").Value));

            if (hasChildToBeExcluded.Count() > 0)
            {
                parentFaktura.Remove();
            }
        }

有人有什么好主意吗?我想有一个不错的onliner。上面的 C# 代码并不能真正解决问题。

谢谢 // R

通过使用 linq 到 xml:
1 - 搜索 excluded 列表中存在的所有元素,如以下代码:

var xmlDoc = XDocument.Load(file.FullName);
List<string> excluded = new List<string> { "112659", "112800", "113201" };

List<XElement> elementsToRemove = xDocument.Descendants("number")
    .Where(x => excluded.Contains(x.Value))
    .ToList();

2 - 获取列表 elementsToRemove 中任何元素的祖先并将其删除:

foreach(XElement xElement in elementsToRemove)
{
    xElement.Ancestors("fakturor").Remove();
}
xmlDoc.Save(fileName);

3 - 演示:

Console.WriteLine(xDocument);

4 - 结果:

<file>
  <fakturor>
    <kund>
      <number>11354</number>
    </kund>
    <faktura>
      <number>112657</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
  <fakturor>
    <kund>
      <number>24202</number>
    </kund>
    <faktura>
      <number>112661</number>
    </faktura>
    <faktura>
      <number>112662</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
</file>

希望对您有所帮助。

LINQ to XML Contains()方法可以模拟SQL的IN子句。它允许在没有任何循环的情况下使用基于集合的操作。

检查一下。

c#

void Main()
{
    const string fileName = @"e:\temp\fakturor.xml";
    const string FAKTURA = "faktura";
    const string FAKTUROR = "fakturor";

    // list of exclusion values
    List<string> listOfExcluded = new List<string> { "112659", "112800", "113201" };

    XDocument xdoc = XDocument.Load(fileName);
    List<XElement> nodes = xdoc.Descendants(FAKTURA).ToList();

    // Contains() simulates SQL: IN clause
    nodes.Elements()
        .Where(x => listOfExcluded.Contains(x.Value))
        .Ancestors(FAKTUROR)
        .Remove();

    Console.WriteLine(xdoc);
    xdoc.Save(fileName);
}

Output

<file>
  <fakturor>
    <kund>
      <number>11354</number>
    </kund>
    <faktura>
      <number>112657</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
  <fakturor>
    <kund>
      <number>24202</number>
    </kund>
    <faktura>
      <number>112661</number>
    </faktura>
    <faktura>
      <number>112662</number>
    </faktura>
    <sum_total_fakturor />
  </fakturor>
</file>