XML C# Как удалить родительский элемент, если какой-либо из нескольких дочерних элементов содержит значение в массиве - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть файл 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", где есть дочерняя фактура с номером = 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();
            }
        }

У кого-нибудь есть какие-нибудь яркие идеи? Я хотел бы иметь хороший лайнер. Приведенный выше код C# на самом деле не помогает.

Спасибо // R

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

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);
}

Вывод

<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>
1 голос
/ 14 апреля 2020

Используя linq to 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>

Я надеюсь, что это поможет вам.

...