Удаление только последовательных повторяющихся элементов XML в C # - PullRequest
0 голосов
/ 17 октября 2019

Итак, у меня есть список элементов XML, которые я хочу просмотреть и удалить дубликаты элементов. По мере прохождения цикла, если между текущим индексом и индексом + 1 найден дубликат, необходимо удалить индекс + 1, а следующим значением, которое следует сравнить с индексом, должен быть индекс + 2 и т. Д., Пока в последовательности не будет дубликатов. ,Если индекс + 3 не является дубликатом по сравнению с индексом, тогда цикл должен продолжаться в обычном режиме для последовательных дублирований.

<Update>
  <Properties id="42" rotation="0.00 0.00 -0.01" />
</Update>

<Update>
  <Properties id="42" rotation="0.00 0.00 -0.01" />
</Update>

<Update>
  <Properties id="42" rotation="0.00 0.00 -0.01" />
</Update>

<Update>
  <Properties id="42" rotation="2.42 2.24 -4.42" />
</Update>

В настоящее время я использую LinQ для манипулирования элементами XDocument. В настоящее время я использую оператор If для сравнения индекса с индексом + 1, и если они совпадают, я удаляю индекс + 1. Когда я ++;тогда индекс теперь находится в позиции, в которой ранее был удален атрибут, следовательно, если следующий индекс + 1 теперь содержит то же значение, что и индекс -2 (поскольку мы увеличили его на 1 на следующей итерации), последовательный дубликат не регистрируется. Токовый выход:

if (xmlElementList.Count() > 1) {

  // Start looping through all modifications
  for (int i = 0; i < xmlElementList.Count() - 1; i++) {
    var currEl = xmlElementList.ElementAt(i).Element("Properties");
    var nextEl = xmlElementList.ElementAt(i+1).Element("Properties");

    // Check for duplicate rotation attributes
    if (currEl.Attribute("rotation") != null) {
      if (currEl.Attribute("rotation ").Value ==
      nextEl.Attribute("rotation ").Value) {

        nextEl.Attribute("rotation ").Remove();
      }
    }
  }              
}
<Update>
    <Properties id="42" rotation="0.00 0.00 -0.01" />
  </Update>
  <Update>
    <Properties id="42" />
  </Update>
  <Update>
    <Properties id="42" rotation="0.00 0.00 -0.01" />
  </Update>
<Update>
    <Properties id="42" rotation="2.42 2.24 -4.42" />
  </Update>

В последовательности не должно быть двух дубликатов. Если в самом файле есть дубликаты, это нормально, но индекс + 1 не должен содержать то же значение, что и индекс. Ожидаемый результат:

<Update>
  <Properties id="42" rotation="0.00 0.00 -0.01" />
</Update>

<Update>
  <Properties id="42" />
</Update>

<Update>
  <Properties id="42" />
</Update>

<Update>
  <Properties id="42" rotation="2.42 2.24 -4.42" />
</Update>

1 Ответ

0 голосов
/ 18 октября 2019

Проблема с вашим текущим подходом заключается в том, что вы продвигаете элемент, на который смотрите слишком рано. При первом совпадении вы должны сравнить исходный первый элемент со следующим после. Вы смотрите только на соседние элементы.

Вы можете создать запрос xpath, в котором довольно легко можно выбрать <Update> элементы, которые имеют тот же идентификатор и поворот, что и предыдущий.

//Update[preceding-sibling::Update/Properties/@id      =Properties/@id
     and preceding-sibling::Update/Properties/@rotation=Properties/@rotation]

Затем измените эти элементы по мере необходимости.

var xpath = "//Update[preceding-sibling::Update/Properties/@id=Properties/@id and preceding-sibling::Update/Properties/@rotation=Properties/@rotation]";
var fixUpdates = doc.XPathSelectElements(xpath);
var fixProperties = fixUpdates.Elements("Properties");
var removeMe = fixProperties.Attributes("rotation");
removeMe.Remove();
...