【问题标题】:XMLDiff / XMLUnit - Ignore Child Order & use of wildcardsXMLDiff / XMLUnit - 忽略子顺序和通配符的使用
【发布时间】:2017-09-15 11:59:41
【问题描述】:

我目前在比较 2 个 xmls 时遇到一个问题 - 原始文件和差异参考文件。问题是当我尝试应用通配符与不同的子顺序进行比较时 - 此外,这些子节点在节点中可能具有不同数量的属性,因此比较更加困难。

我尝试使用适用于 .NET 的 XMLUnit 和 XMLDiff 库实现解决方案,但没有成功。

using System;
using Org.XmlUnit.Builder;
using Org.XmlUnit.Diff;
using System.IO;

static void Main(string[] args)
    {
        string orgFilePath = @"C:\Temp\original.xml";
        string refFilePath = @"C:\Temp\reference.xml";

        StreamReader orgStreamReader = new StreamReader(orgFilePath);
        StreamReader refStreamReader = new StreamReader(refFilePath);

        String orgFile = XDocument.Load(orgStreamReader).ToString();
        String refFile = XDocument.Load(refStreamReader).ToString();

        var diff = DiffBuilder
            .Compare(Input.FromString(orgFile))
            .WithTest(Input.FromString(refFile))
            .CheckForSimilar()
            .Build();

        foreach (var d in )
        {
            Console.WriteLine(d.Comparison);
            Console.WriteLine();
        }
        Console.WriteLine(diff.Differences);

        Console.ReadLine();
    }

参考文件:

<deviceOrders>
    <deviceOrder>
      <operation>New</operation>
      <moduleId>*</moduleId>
      <net>TST</net>
      <sort>VT</sort>
      <moduleNr>220</moduleNr>
      <deviceNr>0</deviceNr>
    </deviceOrder>
    <deviceOrder>
      <operation>New</operation>
      <moduleId>*</moduleId>
      <net>79ST</net>
      <sort>UP</sort>
      <deviceNr>0</deviceNr>
    </deviceOrder>
</deviceOrders>

组织文件:

<deviceOrders>
    <deviceOrder>
      <operation>New</operation>
      <moduleId>1235</moduleId>
      <net>79ST</net>
      <sort>UP</sort>
      <deviceNr>0</deviceNr>
    </deviceOrder>
    <deviceOrder>
      <operation>New</operation>
      <moduleId>1234</moduleId>
      <net>TST</net>
      <sort>VT</sort>
      <moduleNr>220</moduleNr>
      <deviceNr>0</deviceNr>
    </deviceOrder>
</deviceOrders>

我还没有找到解决方案,所以请帮助我。

【问题讨论】:

  • 只是一个疯狂的想法,但它可能有效:您可以定义一个镜像所有可能的子元素和属性的类,让可选的可以为空,然后反序列化两个 XML 并再次序列化它们。然后,您应该有两个具有相同结构的 XML。

标签: c# xml xmldiff xmlunit-2


【解决方案1】:

我觉得对你有帮助

Diff d = DiffBuilder.Compare(Input.FromFile("doc1.xml"))
                    .WithTest(Input.FromFile("doc2.xml")).WithNodeFilter(x=>!x.Name.Equals("NodeName")).Build();
Assert.IsFalse(d.HasDifferences());

ISource control = Input.FromFile("doc1.xml").Build();
ISource test = Input.FromFile("doc2.xml").Build();
IDifferenceEngine diff = new DOMDifferenceEngine();
diff.NodeFilter = x => !x.Name.Equals("NodeName");
diff.DifferenceListener += (comparison, outcome) => {
   Assert.Fail("found a difference: {0}", comparison);
};
diff.Compare(control, test);

【讨论】:

    【解决方案2】:

    尝试运行这个:

    using System;
    using System.Reflection;
    using System.Linq;
    using System.Xml.Linq;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string xml1 = "<?xml version=\"1.0\" encoding=\"UTF - 8\"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>";
                string xml2 = "<?xml version=\"1.0\" encoding=\"UTF - 8\"?> <note> <to>dd22</to> <from>Jani</from> <heading>4fewfewe</heading> <body>Don't forget me this weekend!</body> </note>";
    
                XDocument doc1 = XDocument.Parse(xml1);
                XDocument doc2 = XDocument.Parse(xml2);
                Console.WriteLine("Elements in document 1");
                foreach (string Different in doc1.Elements().Elements().Select(x => x.Value))
                {
                    Console.WriteLine("1----"+Different);
                }
                Console.Read();
    
                Console.WriteLine("Elements in document 2");
                foreach (string Different in doc2.Elements().Elements().Select(x => x.Value))
                {
                    Console.WriteLine("2----" + Different);
                }
    
                Console.Read();
    
                Console.WriteLine("These are the equal elements, I will discard different ones");
                foreach (string Different in doc1.Elements().Elements().Select(x => x.Value).Intersect(doc2.Elements().Elements().Select(x => x.Value)))
                {
                    Console.WriteLine(Different);
                }
                Console.Read();
            }
        }
    }
    

    它将只检索相等的元素。在 foreach 中修改 LINQ 以获得你所需要的。

    它在操作其后代的元素级别上进行节点值的交集。你可以对你的 xml 做同样的事情。

    【讨论】:

    • 这并不能真正解决那里的问题。在您的场景中,当您启动交叉点时,它只检查即使在不同属性中也可以相同的值。解决方案必须保持 XML 节点的层次特征。但无论如何感谢您的贡献。
    • @codi89 也许你不知道这个社区的精神。这不仅仅是嘿我写了这个解决方案pl0x。您可以使用 Reflection 或 XElement 名称属性轻松保持分层树和命名,并从我为您编写的代码中轻松制定解决方案。这并不难,您可以根据我的代码比较节点名称和位置或轻松检索不同的元素
    猜你喜欢
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多