XDocument Сравнение - PullRequest
       15

XDocument Сравнение

0 голосов
/ 17 декабря 2009

У меня есть два документа с простой схемой, которую мне нужно сравнить:

текущий документ:

<Sections>
  <Section Number="1"/>
  <Section Number="2"/>
  <Section Number="4"/>
  <Section Number="5"/>
</Sections>

предыдущий документ:

<Sections>
  <Section Number="1"/>
  <Section Number="2"/>
</Sections>

Результатом сравнения будет список разделов, которые были добавлены в текущий документ ... то есть разделы в текущем документе, которых нет в предыдущем документе. В этом примере разделы 4 и 5 являются новыми.

Текущий и предыдущий документ может содержать более 20000 записей. Следующий подход дает нужные мне результаты, но кажется неправильным, так как он проходит по наборам данных несколько раз и требует времени для запуска.

получить список разделов:

List<XElement> currenList = currentDoc.Descendants("Section").ToList();

получить атрибуты в предыдущем списке

List<string> previousString = //get the attribute values...
//get the new sections...
var newSections = (from nodes in currentList
                   let att = nodes.Attribute("Number").Value
                   where !previousList.Contains(att)
                   select nodes) 

Что является лучшим подходом, который включал бы меньшее количество проходов / преобразований наборов данных?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2009

Вы можете использовать отсортированный набор для отслеживания.

SortedSet<string> sections = new Sort...
List<XElement> diff = new Li...

foreach (var node in previousList)
    sections.Add(node.Attribute("Section").Value());

foreach (var node in currentList)
    if (!sections.Contains(node.Attribute("Section").Value());
        diff.Add(node);

это использует немного дополнительной памяти с SortedSet, но он должен запустить n * log (n), так как Contains () для отсортированного набора запустит log (n).

в конце, diff должен содержать список, который вы ищете.

0 голосов
/ 17 декабря 2009

Вы должны посмотреть на Except:

IEnumerable<int> currentList = currentDoc.Descendants("Section")
                      .Select(e => (int)e.Attribute("Number"));
IEnumerable<int> previousList = previousDoc.Descendants("Section")
                      .Select(e => (int)e.Attribute("Number"));

IEnumerable<int> newSections = currentList.Except(previousList);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...