我想将两个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