推荐使用XNode.DeepEquals进行XML语义比较,它自动忽略空白、属性顺序等格式差异,正确处理命名空间URI而非前缀;也可用XmlDocument归一化后字符串比较,或借助Microsoft.XmlDiffPatch实现精细控制。
直接比较两个XML文件的字符串内容通常不可靠,因为格式差异(如空格、换行、属性顺序、命名空间前缀)会导致相同语义的XML字符串不相等。C#中推荐使用基于XML结构和语义的比较方式,核心是用 XmlDocument 或 XDocument 加载后归一化再比对,或借助专门的XML比较库。
XNode.DeepEquals 是 .NET 内置方法,自动忽略空白文本节点、属性顺序、声明、注释(默认不忽略注释,需注意),并按逻辑结构比较元素、属性、值和嵌套关系。
XDocument
XNode.DeepEquals(doc1.Root, doc2.Root) 比较根节点(若文档结构一致)RemoveNodes() 清理,或使用第三方库var doc1 = XDocument.Load("file1.xml");
var doc2 = XDocument.Load("file2.xml");
bool identical = XNode.DeepEquals(doc1.Root, doc2.Root);
当需要完全可控的“标准化输出”时,可将两个 XML 加载为 XmlDocument,用 XmlWriterSettings 设置 Indent=false、OmitXmlDeclaration=true、IgnoreWhitespace=true 等,再写入字符串比较。
PreserveWhitespace = false 可跳过文本节点中的冗余空白Normalize() 方法对文档进行规范化(合并相邻文本节点等)XDocument 配合 XmlNamespaceManager
两个语义相同的XML可能使用不同前缀(如 ns:elem vs abc:elem),但属于同一命名空间URI。此时 DeepEquals 默认能正确识别——它比对的是命名空间URI而非前缀。
XmlReaderSettings.Namespaces = true,默认开启)XElement.Name.NamespaceName,否则会破坏语义一致性doc.Root.Attributes().Where(a => a.IsNamespaceDeclaration) 查看声明这是微软提供的开源XML差
异工具(现维护于 GitHub),支持生成差异补丁、忽略特定节点、自定义比较规则(如忽略时间戳属性、排序子节点后再比)。
Microsoft.XmlDiffPatch
XmlDiff 实例,设置 IgnoreChildOrder、IgnoreComments 等选项,调用 Compare()