Сравнение фрагментов XML и возврат различий

У меня есть контрольный список, полный сериализованных объектов, и я хотел бы сравнить их и вернуть список различия. Под «сравнить» я подразумеваю, что хочу вернуться туда, где изменился текст для элемента или где был добавлен узел (так что это не в Xml1, а в Xml2 - это не произойдет наоборот)

​​Пример xml:

<HotelBookingView xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>119</Id>
  <RoomId>1</RoomId>
  <ChangeRequested>false</ChangeRequested>
  <CourseBookings>      
    <CourseHotelLink>
      <Id>0</Id>
    </CourseHotelLink>
</CourseBookings>
</HotelBookingView>

Пространства имен и имена/регистр тегов не изменятся. Все, что может измениться в этом образце, — это значения между тегами и количество «CourseHotelLink» (это сериализованный список).

Конечным результатом, который мне нужен, является список узлов, которые изменились: старое значение и новое значение.

Как лучше их сравнить? Я использую .Net 4.0, поэтому linq — вариант. Мне нужно иметь возможность выполнить сравнение, не обязательно зная имена всех узлов, хотя я буду сравнивать только два объекта одного типа.Я пытался использовать следующий код, но мне не удалось адаптировать его для выделения изменений в тексте, а также дополнительных узлов.

XmlDocument Xml1 = new XmlDocument();
XmlDocument Xml2 = new XmlDocument();
Xml1.LoadXml(list[1].Changes);
Xml2.LoadXml(list[2].Changes);
foreach (XmlNode chNode in Xml2.ChildNodes)
{
   CompareLower(chNode);
}

protected void CompareLower(XmlNode aNode)
{
    foreach (XmlNode chlNode in aNode.ChildNodes)
    {
        string Path = CreatePath(chlNode);
        if (chlNode.Name == "#text")
        {
            //all my efforts at comparing text have failed
            continue;
        }
        if (Xml1.SelectNodes(Path).Count == 0)
        {
            XmlNode TempNode = Xml1.ImportNode(chlNode, true);
            //node didn't used to exist, this works- though doesn't return values
            str = str + "New Node: " + TempNode.Name + ": " + TempNode.Value;
        }
        else
        {
            CompareLower(chlNode);
        }
    } 
}

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

ОТРЕДАКТИРОВАНО: добавлено: В итоге я использовал MS Xml Diff Tool, следующий код создает большой список html-таблиц двух узлов xml с различиями, выделенными зеленым цветом. Таким образом, возможно (хотя и безумно) создать html, затем отсортировать его, чтобы найти текст «светло-зеленый» (выделенное значение), а затем выполнить некоторые формации строк, чтобы отобразить только измененный дочерний узел.

var node1 = XElement.Parse("Xml string 1 here").CreateReader();
var node2 = XElement.Parse("Xml string 2 here").CreateReader();

MemoryStream diffgram = new MemoryStream();
XmlTextWriter diffgramWriter = new XmlTextWriter(new StreamWriter(diffgram));

XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder);
xmlDiff.Algorithm = XmlDiffAlgorithm.Fast;
xmlDiff.Compare(node1, node2,diffgramWriter);

diffgram.Seek(0, SeekOrigin.Begin);
XmlDiffView xmlDiffView = new Microsoft.XmlDiffPatch.XmlDiffView();
StringBuilder sb = new StringBuilder();
TextWriter resultHtml = new StringWriter(sb);
xmlDiffView.Load("Xml string 1", new XmlTextReader(diffgram)); 

xmlDiffView.GetHtml(resultHtml);
resultHtml.Close();
8
задан UglyTeapot 8 May 2012 в 15:42
поделиться