12

我正在使用 .NET 2.0,最近的代码更改使我之前的 Assert.AreEqual 调用(它比较了两个 XML 字符串)无效。在新的代码库中,只有一个 XML 元素实际上是不同的,所以我希望所有其他元素的比较会给我想要的结果。比较需要以编程方式完成,因为它是单元测试的一部分。

起初,我正在考虑使用几个 XmlDocument 实例。但后来我发现了这个: http ://drowningintechnicaldebt.com/blogs/scottroycraft/archive/2007/05/06/comparing-xml-files.aspx

看起来它可能会起作用,但我对 Stack Overflow 的反馈很感兴趣,以防有更好的方法。

如果可能的话,我想避免为此添加另一个依赖项。

类似问题

4

7 回答 7

11

这实际上取决于您要检查的“差异”。

现在,我们正在使用 Microsoft XmlDiff:http: //msdn.microsoft.com/en-us/library/aa302294.aspx

于 2008-11-18T17:56:24.533 回答
4

您可能会发现将 XML 解析为 XmlDocument 并将您的 Assert 调用基于 XPath Query 并不那么脆弱。以下是我经常使用的一些辅助断言方法。每一个都需要一个 XPathNavigator,您可以通过在 XmlDocument 或从文档中检索的任何节点上调用 CreateNavigator() 来获得它。一个使用示例是:

     XmlDocument doc = new XmlDocument( "Testdoc.xml" );
     XPathNavigator nav = doc.CreateNavigator();
     AssertNodeValue( nav, "/root/foo", "foo_val" );
     AssertNodeCount( nav, "/root/bar", 6 )

    private static void AssertNodeValue(XPathNavigator nav,
                                         string xpath, string expected_val)
    {
        XPathNavigator node = nav.SelectSingleNode(xpath, nav);
        Assert.IsNotNull(node, "Node '{0}' not found", xpath);
        Assert.AreEqual( expected_val, node.Value );
    }

    private static void AssertNodeExists(XPathNavigator nav,
                                         string xpath)
    {
        XPathNavigator node = nav.SelectSingleNode(xpath, nav);
        Assert.IsNotNull(node, "Node '{0}' not found", xpath);
    }

    private static void AssertNodeDoesNotExist(XPathNavigator nav,
                                         string xpath)
    {
        XPathNavigator node = nav.SelectSingleNode(xpath, nav);
        Assert.IsNull(node, "Node '{0}' found when it should not exist", xpath);
    }

    private static void AssertNodeCount(XPathNavigator nav, string xpath, int count)
    {
        XPathNodeIterator nodes = nav.Select( xpath, nav );
        Assert.That( nodes.Count, Is.EqualTo( count ) );
    }
于 2008-11-18T18:46:35.850 回答
1

对字符串进行简单的字符串比较xml并不总是有效。为什么 ?

例如两者:

<MyElement></MyElmennt>并且<MyElment/>从一个角度来看是平等的xml..

有一些用于转换的算法xml总是看起来相同,它们被称为规范化算法。.Net支持规范化。

于 2008-11-18T18:08:12.667 回答
1

我编写了一个带有用于序列化的断言的小型库source

样本:

[Test]
public void Foo()
{
   ...
   XmlAssert.Equal(expected, actual, XmlAssertOptions.IgnoreDeclaration | XmlAssertOptions.IgnoreNamespaces);
}

NuGet

于 2016-04-29T06:45:35.220 回答
0

由于 XML 文件的内容可以具有不同的格式,并且在测试相等性时仍然被认为是相同的(从 DOM 的角度来看),因此您需要确定该相等性的度量是什么,例如,格式是否被忽略?元数据是否被忽略等定位很重要,很多边缘情况。

通常,您会创建一个定义相等规则的类并将其用于比较,如果您的比较类实现了IEqualityComparer and/or IEqualityComparer<T>接口,那么您的类也可以在一堆内置框架列表中用作相等测试实现。另外,当然,您可以根据需要以不同的方式衡量平等。

IE

IEnumerable<T>.Contains
IEnumerable<T>.Equals
The constructior of a Dictionary etc etc
于 2008-11-18T21:43:56.133 回答
0

我最终通过以下代码得到了我想要的结果:

private static void ValidateResult(string validationXml, XPathNodeIterator iterator, params string[] excludedElements)
    {
        while (iterator.MoveNext())
        {
            if (!((IList<string>)excludedElements).Contains(iterator.Current.Name))
            {
                Assert.IsTrue(validationXml.Contains(iterator.Current.Value), "{0} is not the right value for {1}.", iterator.Current.Value, iterator.Current.Name);
            }
        }
    }

在调用该方法之前,我以这种方式在 XmlDocument 的实例上创建一个导航器:

XPathNavigator nav = xdoc.CreateNavigator();

接下来,我创建一个 XPathExpression 实例,如下所示:

XPathExpression expression = XPathExpression.Compile("/blah/*");

我在使用表达式创建迭代器后调用该方法:

XPathNodeIterator iterator = nav.Select(expression);

我仍在研究如何进一步优化它,但它现在可以解决问题。

于 2008-11-19T23:08:44.853 回答
0

我做了一个方法来创建简单的 XML 路径。

static XElement MakeFromXPath(string xpath)
{
    XElement root = null;
    XElement parent = null;
    var splits = xpath.Split('/'); //split xpath into parts
    foreach (var split in splits)
    {
        var el = new XElement(split);
        if (parent != null)
            parent.Add(el);
        else
            root = el; //first element created, set as root
        parent = el;
    }
    return root;
}

示例用法:

var element = MakeFromXPath("My/Path/To/Element")'

element将包含值:

<My>
  <Path>
    <To>
      <Element></Element>
    </To>
  </Path>
</My>
于 2019-10-28T18:14:01.590 回答