2009-04-27 74 views
13

我想比较两个使用C#代码的Xml文件。 我想忽略Xml语法差异(即前缀名称)。 为此,我使用微软的XML Diff and Patch C#API。 它适用于某些XML的,但我无法找到一个方法来配置它具有以下两个XML的工作:在C#中的Xml比较

XML答:

<root xmlns:ns="http://myNs"> 
    <ns:child>1</ns:child> 
</root> 

XML B:

<root> 
    <child xmlns="http://myNs">1</child> 
</root> 

我问题是:

  1. 我说得对,这两个XML的语义相同(或同构)?
  2. Microsoft的XML Diff和Patch API可以配置为支持它吗?
  3. 是否有任何其他C#实用程序来这?

回答

2

我在an answer by Martin Honnen XML和.NET Framework MSDN论坛。 总之,他建议使用XQuery 1.0的深层平等功能并提供一些C#实现。似乎工作。

2

我知道你关注的不是单元测试,但XMLUnit可以比较两个XML文件,我认为它能够解决你的例子。也许你可以看看代码并找出你的解决方案。

+0

其实我的重点是单元测试。 但是,XMLUnit在.Net中似乎也有类似的限制。它实际上适用于上面的Xml,但有一点变化打破了它。 – 2009-04-28 12:01:37

1

从每个xml文件中加载XmlDocument实例并比较XML DOM可能是一个想法吗?为每个人提供正确的验证,这应该为您提供一个比较的共同点,并且应该允许标准差异报告。可能甚至是用三角洲更新另一个的能力。

+0

这是一个选项 - 但它自己做了一件我认为是常见问题的解决方案。 – 2009-04-28 12:02:29

0

这些文档在语义上并不相同。第一个元素的顶层元素位于http://myNS名称空间中,而第二个元素的顶层元素位于默认名称空间中。

孩子这两个文件的元素是等价的。但文件本身不是。

编辑:

有天壤之别xmls:ns='http://myNS'xmlns='http://myNS'之间,我似乎已经忽略了。无论如何,这些文件在语义上是相同的,我只是错了。

+0

这是不正确的。这两个文档的顶层元素都在默认的命名空间中。如果第一个文档的顶层元素声明为 ,则第一个文档的顶层元素只能位于http:// myNs命名空间中。 “http:// myNs”> – 2009-04-27 19:16:49

10

这些文件是同构的,可以通过下面的程序显示。我想如果你使用XmlDiffOptions.IgnoreNamespacesXmlDiffOptions.IgnorePrefixes来配置Microsoft.XmlDiffPatch.XmlDiff,你会得到你想要的结果。

using System.Linq; 
using System.Xml.Linq; 
namespace SO_794331 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var docA = XDocument.Parse(
       @"<root xmlns:ns=""http://myNs""><ns:child>1</ns:child></root>"); 
      var docB = XDocument.Parse(
       @"<root><child xmlns=""http://myNs"">1</child></root>"); 

      var rootNameA = docA.Root.Name; 
      var rootNameB = docB.Root.Name; 
      var equalRootNames = rootNameB.Equals(rootNameA); 

      var descendantsA = docA.Root.Descendants(); 
      var descendantsB = docB.Root.Descendants(); 
      for (int i = 0; i < descendantsA.Count(); i++) 
      { 
       var descendantA = descendantsA.ElementAt(i); 
       var descendantB = descendantsB.ElementAt(i); 
       var equalChildNames = descendantA.Name.Equals(descendantB.Name); 

       var valueA = descendantA.Value; 
       var valueB = descendantB.Value; 
       var equalValues = valueA.Equals(valueB); 
      } 
     } 
    } 
} 
+1

IgnoreNamespaces对我不好 - 我认为具有不同名称空间的文档在语义上是不同的。 – 2009-04-28 12:03:00