在C#项目中,比较两个XML文件是否相同不能只靠文本相等判断,因为缩进、换行、属性顺序不同都会导致字符串不一致,但语义上却是同一个XML。我们需要在解析后比较文档的结构与数据内容。

使用XmlDocument进行结构化比较
XmlDocument是传统的XML处理类,可以加载文件并忽略空白节点,再通过递归遍历子节点来比对名称、属性和文本。
using System;
using System.Xml;
public class XmlComparer
{
public static bool Compare(XmlNode n1, XmlNode n2)
{
if (n1 == null || n2 == null) return n1 == n2;
if (n1.Name != n2.Name) return false;
if (n1.InnerText.Trim() != n2.InnerText.Trim()) return false;
// 比较属性
if (n1.Attributes.Count != n2.Attributes.Count) return false;
for (int i = 0; i < n1.Attributes.Count; i++)
{
var a1 = n1.Attributes[i];
var a2 = n2.Attributes[a1.Name];
if (a2 == null || a1.Value != a2.Value) return false;
}
// 比较子节点
var c1 = n1.ChildNodes;
var c2 = n2.ChildNodes;
if (c1.Count != c2.Count) return false;
for (int i = 0; i < c1.Count; i++)
{
if (!Compare(c1[i], c2[i])) return false;
}
return true;
}
public static void Main()
{
XmlDocument doc1 = new XmlDocument();
doc1.LoadXml("<root><item id='1'>hello</item></root>");
XmlDocument doc2 = new XmlDocument();
doc2.LoadXml("<root><item id='1'>hello</item></root>");
bool same = Compare(doc1.DocumentElement, doc2.DocumentElement);
Console.WriteLine(same);
}
}
使用XDocument与LINQ简化比较
XDocument配合LINQ to XML写起来更简洁,适合现代C#代码。下面的方法会忽略空白文本节点,比较元素名、属性和子元素。
using System;
using System.Linq;
using System.Xml.Linq;
public class XComparer
{
public static bool Equals(XElement e1, XElement e2)
{
if (e1.Name != e2.Name) return false;
if (e1.Attributes().Count() != e2.Attributes().Count()) return false;
if (!e1.Attributes().All(a =>
e2.Attribute(a.Name)?.Value == a.Value)) return false;
var c1 = e1.Elements().ToList();
var c2 = e2.Elements().ToList();
if (c1.Count != c2.Count) return false;
return c1.Zip(c2, (a, b) => Equals(a, b)).All(x => x);
}
public static void Run()
{
XDocument d1 = XDocument.Parse("<root><x>1</x></root>");
XDocument d2 = XDocument.Parse("<root><x>1</x></root>");
Console.WriteLine(Equals(d1.Root, d2.Root));
}
}
处理命名空间
如果XML带有命名空间,比较时要确保Name包含的命名空间一致,或者使用XName的LocalName与Namespace分别判断。
注意事项
- 加载时设置
XmlReaderSettings.IgnoreWhitespace可避免空白节点干扰 - 属性顺序不同但值相同应视为相同XML
- 注释节点一般不影响业务数据,可跳过比较
实际项目中建议封装成通用方法,并针对业务决定是否比较元素顺序。
C#XMLXML_compare修改时间:2026-07-28 12:27:25