2

我一直在努力使用 XmlComparsion 功能。我必须比较两个 Xml 的差异,然后以 TreeView 的方式显示它们。

我做了一些研究,发现 Google Diff Match Patch 库看起来正是我的比较部分所需要的。

https://github.com/google/diff-match-patch

我已将其实现如下

public List<Diff> DiffLineMode(string text1, string text2)
        {
            var a = base.diff_linesToChars(text1, text2);
            var lineText1 = a[0];
            var lineText2 = a[1];
            var lineArray = (IList<string>)a[2];
            var diffs = base.diff_main(lineText1.ToString(), lineText2.ToString(), false);
            base.diff_charsToLines(diffs, lineArray);

                  return diffs;
        } 

现在,我需要一些帮助的最大挑战是将这种差异变成像对象一样的树视图。

我已经完成了一个树视图类,我在其中解析了比较使用的两个 Xml 文件

public class TreeViewModel
    {
        public long ID { get; set; }
        public string NodeName { get; set; }
        public string AbsolutPath { get; set; }
        public string Value { get; set; }
        public string Xml { get; set; }
        public int Operation { get; set; } = 2;
        public List<TreeViewModel> Children { get; set; }
        public Dictionary<string, string> Attributes { get; set; }
    } 

现在我想做的是确保来自 TreeView 的操作与来自 DIffMatchPatch 的操作结果相匹配,但我的问题是 DiffMatchPatch 将 Xml 比较为字符串并且根本不将 Xml 视为节点树。结果是 2 个简单的 Xml 书籍文件。

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk112">
      <author>Ralls, Kim</author>
      <title>Midnight Rain Update but should not reflect</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk999">
      <author>O'Brien, Tim</author>
      <title>Microsoft .NET: The Programming Bible</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-09</publish_date>
      <description>Microsoft's .NET initiative is explored in 
      detail in this deep programmer's reference.</description>
   </book>  
   <book id="bk998">
      <author>Chris Tucker</author>
      <title>This Is my Churck</title>
      <genre>Music</genre>
      <price>49.99</price>
      <publish_date>2021-11-03</publish_date>
      <description>This is a custom description from Sebi Ciuca</description>
      <coauthor>Sebi</coauthor>
   </book>    
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
</catalog>

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
   <book id="bk997">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant Part II</title>
      <genre>Fantasy</genre>
      <price>15.95</price>
      <publish_date>2022-01-17</publish_date>
      <description>After one collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
</catalog>

它会输出这个

 "difference": [
    {
      "operation": 2,
      "text": "<catalog>\r\n  <book id=\"bk101\">\r\n    <author>Gambardella, Matthew</author>\r\n    <title>XML Developer's Guide</title>\r\n    <genre>Computer</genre>\r\n    <price>44.95</price>\r\n    <publish_date>2000-10-01</publish_date>\r\n    <description>An in-depth look at creating applications \r\n      with XML.</description>\r\n  </book>\r\n"
    },
    {
      "operation": 0,
      "text": "  <book id=\"bk112\">"
    },
    {
      "operation": 1,
      "text": "  <book id=\"bk102\">"
    },
    {
      "operation": 2,
      "text": "    <author>Ralls, Kim</author>\r\n    <genre>Fantasy</genre>\r\n    <price>5.95</price>\r\n    <publish_date>2000-12-16</publish_date>\r\n    <description>A former architect battles corporate zombies, \r\n      an evil sorceress, and her own childhood to become queen \r\n      of the world.</description>\r\n  </book>\r\n"
    },
    {
      "operation": 0,
      "text": "  <book id=\"bk999\">    <author>O'Brien, Tim</author>    <title>Microsoft .NET: The Programming Bible</title>    <genre>Computer</genre>    <price>36.95</price>    <publish_date>2000-12-09</publish_date>    <description>Microsoft's .NET initiative is explored in       detail in this deep programmer's reference.</description>  </book>  <book id=\"bk998\">    <author>Chris Tucker</author>    <title>This Is my Churck</title>    <genre>Music</genre>    <price>49.99</price>    <publish_date>2021-11-03</publish_date>    <description>This is a custom description from Sebi Ciuca</description>    <coauthor>Sebi</coauthor>  </book>"
    },
    {
      "operation": 2,
      "text": "  <book id=\"bk103\">\r\n    <author>Corets, Eva</author>\r\n    <title>Maeve Ascendant</title>\r\n    <genre>Fantasy</genre>\r\n    <price>5.95</price>\r\n    <publish_date>2000-11-17</publish_date>\r\n    <description>After the collapse of a nanotechnology \r\n"
    },
    {
      "operation": 1,
      "text": "      society in England, the young survivors lay the       foundation for a new society.</description>  </book>  <book id=\"bk997\">    <author>Corets, Eva</author>    <title>Maeve Ascendant Part II</title>    <genre>Fantasy</genre>    <price>15.95</price>    <publish_date>2022-01-17</publish_date>    <description>After one collapse of a nanotechnology "
    },
    {
      "operation": 2,
      "text": "      society in England, the young survivors lay the \r\n      foundation for a new society.</description>\r\n  </book>\r\n</catalog>"
    }
  ]

在更“可读”的视图中看起来像这样

在此处输入图像描述

现在您可以看到,如果您有 2 个或更多节点差异,它们作为“孔差异”在内部“放置”在一起,这让我将其解析为类似树视图的对象非常棘手。

在这里您还可以看到 book997 是一本新书,但与 book103 的描述相同,它将考虑从 book 103 的描述开始并在 book997 的描述之前结束的“添加”文本。在某种程度上,我想将两个节点都更改为节点,但我不知道我可以使用什么来匹配特定的 TreeView 节点与差异的一部分或孔。

希望我说清楚了。我开始觉得我开始对 GoogleDiffMatchPatch 的需求非常错误,但在这一点上,我更难创建基于节点的自定义 xml 比较器。

编辑:还添加了从 XML 到 TreeView 的解析

 public TreeViewModel ToTreeView(XDocument xmlDocument)
        {
            var rootNode = xmlDocument.Root;

            return ParseNode(rootNode, 1);
        }

  private TreeViewModel ParseNode(XElement node, int parentId)
        {
            if (node.HasElements)
            {
                var index = 0;
                var children = new List<TreeViewModel>();
                bool hasChild = false;
                foreach (var element in node.Elements())
                {
                    children.Add(ParseNode(element, parentId * 10 + index, panoramaId));
                    index++;
                }

                var treeNode = new TreeViewModel
                {
                    Children = children,
                    Value = hasChild ? string.Empty : node.Value,
                    AbsolutPath = node.GetAbsoluteXPath(),
                    ID = parentId,
                    Xml = node.ToString(),
                    NodeName = node.Name.ToString(),
                    Attributes = node.GetAttributes()
                };
            }
            else
            {
                var treeNode = new TreeViewModel
                {
                    ID = parentId,
                    Value = node.Value,
                    AbsolutPath = node.GetAbsoluteXPath(),
                    NodeName = node.Name.ToString(),
                    Attributes = node.GetAttributes(),
                    Xml = node.ToString(),
                };
            }
        }

添加了 git 存储库: https ://github.com/SebiCiuca/DiffMatchPatchToNodeView

4

1 回答 1

-1

看看以下是否有帮助:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication11
{
    class Program
    {
        const string FILENAME1 = @"c:\temp\test.xml";
        const string FILENAME2 = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {
            TreeViewModel model = new TreeViewModel(FILENAME1, FILENAME2);
        }
    }
    public class TreeViewModel
    {
        public string AbsolutPath { get; set; }
        public string Value { get; set; }
        public int Operation { get; set; }
        public Catalog catalog1 { get;set;}
        public Catalog catalog2 { get;set;}
        public Dictionary<string, Book> catalog1Dict { get; set; }
        public Dictionary<string, Book> catalog2Dict { get; set; }

        public TreeViewModel(string filename1, string filename2)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
            XmlReader reader = XmlReader.Create(filename1);

            catalog1 = (Catalog)serializer.Deserialize(reader);
            catalog1Dict = catalog1.books.GroupBy(x => x.id).ToDictionary(x => x.Key, y => y.FirstOrDefault());

            reader = XmlReader.Create(filename2);
            catalog2 = (Catalog)serializer.Deserialize(reader);
            catalog2Dict = catalog2.books.GroupBy(x => x.id).ToDictionary(x => x.Key, y => y.FirstOrDefault());

        }
    } 
    [XmlRoot("catalog")]
    public class Catalog
    {
        [XmlElement("book")]
        public List<Book> books { get;set;}
    }
    public class Book
    {
        [XmlAttribute()]
        public string id { get;set;}
        public string author { get;set;}
        public string title { get;set;}
        public string genre { get;set;}
        public decimal price { get;set;}
        public DateTime publish_date { get;set;}
        public string description { get;set;}
    }
}
于 2022-01-07T13:31:14.597 回答