我想将两个xml文档比较为相等。我的一个文档有自动关闭标签,另一个没有。

XNode node = XDocument.Parse("<Root/>");
XNode node2 = XDocument.Parse("<Root></Root>");

bool result = XNode.DeepEquals(node, node2);
Console.WriteLine(result);

Run it quickly
我假设"<Root/>"等同于"<Root></Root>"但是DeepEquals表示它们不是(返回false)。
我怎么能把这两份文件相提并论呢?
注:不受XNode约束。也欢迎使用XmlDocument解决方案。

最佳答案

为了比较两个文档是否相等,应该在一定程度上对它们进行规范化。
埃里克怀特发表了几篇博文,详细介绍了高级规范化[1]和简单规范化[2]。
要修复空标记与自动关闭标记,后一篇文章更为相关。
摘自文章:

static XElement CloneElement(XElement element)
{
    return new XElement(element.Name,
        element.Attributes(),
        element.Nodes().Select(n =>
        {
            XElement e = n as XElement;
            if (e != null)
                return CloneElement(e);
            return n;
        })
    );
}

这段代码将递归地将一个元素及其后代复制到一个规范化的表单中(使用默认的xelement构造)。这包括将空标记规范化为自动关闭标记。然后比较文档将按预期工作。
请考虑以下XML:
<Foo>
    <Bar/>
    <Root/>
</Foo>


<Foo>
    <Bar></Bar>
    <Root></Root>
</Foo>

对每个元素使用CloneElement后,它们将相等。
var node = XElement.Parse("<Foo><Bar/><Root/></Foo>");
var node2 = XElement.Parse("<Foo><Bar></Bar><Root></Root></Foo>");

XElement.DeepEquals(node, node2); // False
XElement.DeepEquals(CloneElement(node), CloneElement(node2)); // True

〔1〕:Equality Semantics of LINQ to XML Trees
〔2〕:Empty Elements and Self-Closing Tags

08-05 17:37