C#:如何在保存前对XML进行排序和缩进?

C#:如何在保存前对XML进行排序和缩进?,c#,xml,sorting,c#-4.0,comparison,C#,Xml,Sorting,C# 4.0,Comparison,我从两个不同的web服务中得到了XML格式的响应。这两个web服务具有相同的逻辑,但使用不同的技术开发。我们正在将web服务转移到Microsoft技术。web服务引擎是连接到许多其他应用程序并向其提供不同服务的核心 每当有对生产web服务的调用时,我们都会将类似的调用传递给在Microsoft Technologies上开发的web服务,并将两个响应保存在单独的文件夹中 现在,我们必须比较两个响应(XML)。有很多排序和预期问题。我想避免所有的排序和缩进问题,这样我就可以得到正确的比较报告 有

我从两个不同的web服务中得到了XML格式的响应。这两个web服务具有相同的逻辑,但使用不同的技术开发。我们正在将web服务转移到Microsoft技术。web服务引擎是连接到许多其他应用程序并向其提供不同服务的核心

每当有对生产web服务的调用时,我们都会将类似的调用传递给在Microsoft Technologies上开发的web服务,并将两个响应保存在单独的文件夹中

现在,我们必须比较两个响应(XML)。有很多排序和预期问题。我想避免所有的排序和缩进问题,这样我就可以得到正确的比较报告

有什么方法可以排序和缩进吗 在保存XML之前(XMLDocument.Save)它

谢谢


解决方案:

我在网上找到了一些XSLT,但似乎有一个 当元素具有属性时出现问题

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-template select="@* | node()">
            <xsl:sort select="name()"/>
        </xsl:apply-template>
    </xsl:copy>
</xsl:template>

实际上,属性节点必须先复制到结果树,然后再复制到其他类型的任何节点。由于排序,节点集会丢失文档顺序,因此无法再保证属性的处理早于元素和文本节点

一个解决方案是:

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@*">
            <xsl:sort select="name()"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="node()">
            <xsl:sort select="name()"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

但是,由于结果树序列化后属性的相对输出顺序取决于处理器,因此您不妨省略属性排序:

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates select="node()">
            <xsl:sort select="name()"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>


感谢史努比和其他人的帮助

如果使用文本差异工具进行比较,则需要修复缩进。但是,如果您使用XML比较工具进行比较,或者如果您编写了一个在节点上迭代并进行比较的工具,那么缩进就没有意义了


查看XML Diff工具,例如Altova提供的工具:

如果它与您想要的不同,并且您只关心它本身的内容,例如,检查标题是否设置正确,是否缺少任何节点

我强烈建议停止手动查看差异

我将创建一个简单的应用程序(windows/web),它将读取这两个文件夹并使用每个文件名(让我们想象它是相同的名称),并对每个节点和属性进行图形化表示,
断言
所有内容都在正确的位置

在该目录中很容易执行并自动处理它们,例如生成
结果
目录甚至数据库或电子邮件的输出

  • 打开文件(使用
    FileSystemWatcher
    避免手动操作)
  • 解析它们(将它们解析为的自定义对象,并将它们作为普通的
    XMLNodeList
    加载)
  • 比较它们(对于原始(旧服务)文件中的每个节点,新服务文件中是否包含该节点?)

    • 我的建议是通过相同的Xslt运行两个XmlDocuments(进行排序和缩进)。生成的XmlDocuments应该很容易(手动)与您选择的工具进行比较。

      我建议使用xmlunit来比较文件,这个nunit扩展名是用c#编写的,并且是免费的。

      如果您喜欢手动比较,也可以这样做:

      XmlDocument doc = new XmlDocument(); doc.LoadXml("bla"); XmlTextWriter writer = new XmlTextWriter("data.xml",null); writer.Formatting = Formatting.Indented; doc.Save(writer); XmlDocument doc=新的XmlDocument(); doc.LoadXml(“bla”); XmlTextWriter=newXMLTextWriter(“data.xml”,null); writer.Formatting=格式化.缩进; 保存文档(编写器);
      当前如何保存XML数据?发布一些代码。@dtb-through-XmlDocument.Save()我很高兴使用Beyond Compare 3 Pro(格式:=XML排序和整理)来比较XML。这只是我想处理的排序和缩进的额外差异。我为什么要创建一个呢?我使用的是“无与伦比”,它在这方面非常有用。@Snoppy谢谢。这涵盖了查询的一半。知道如何在不知道XML的情况下对节点进行排序吗?System.Collections.Generic.SortedDictionary list=new SortedDictionary();XmlNode节点;添加(“您的排序键”,节点);foreach(列表中的当前变量){//write usingXMLwriter}