67

いくつかの広範な単体テストの基本クラスの一部として、C# (.NET) で 1 つの XmlDocument オブジェクトのノードを別のオブジェクトと再帰的に比較するヘルパー関数を作成しています。これのいくつかの要件:

  • 最初のドキュメントはsource です。たとえば、XML ドキュメントをどのように表示したいかです。したがって、2 番目は違いを見つけたいものであり、最初のドキュメントにない余分なノードを含めてはなりません。
  • あまりにも多くの重大な違いが見つかった場合は例外をスローする必要があり、人間が説明を一目見れば簡単に理解できるはずです。
  • 子要素の順序は重要です。属性は任意の順序にすることができます。
  • 一部の属性は無視できます。具体的にはxsi:schemaLocationxmlns:xsiですが、どれがどれであるかを渡したいと思います。
  • 名前空間のプレフィックスは、属性と要素の両方で一致する必要があります。
  • 要素間の空白は無関係です。
  • 要素には子要素またはのいずれかがありますが、両方はありません。 InnerText

私は何かをまとめていますが、そのようなコードを書いた人はいますか?ここで共有できますか?

余談ですが、1 番目と 2 番目のドキュメントを何と呼びますか? 私はそれらを「ソース」と「ターゲット」と呼んでいますが、ソースは私がターゲットに見せたいものであるため、間違っているように感じます。そうでない場合、例外をスローします。

4

13 に答える 13

59

Microsoft には、使用できるXML diff APIがあります。

非公式の NuGet: https://www.nuget.org/packages/XMLDiffPatch

于 2008-10-03T17:22:46.397 に答える
6

このコードはすべての要件を満たしているわけではありませんが、シンプルであり、単体テストに使用しています。属性の順序は重要ではありませんが、要素の順序は重要です。要素の内部テキストは比較されません。属性を比較するときに大文字と小文字も無視しましたが、これは簡単に削除できます。

public bool XMLCompare(XElement primary, XElement secondary)
{
    if (primary.HasAttributes) {
        if (primary.Attributes().Count() != secondary.Attributes().Count())
            return false;
        foreach (XAttribute attr in primary.Attributes()) {
            if (secondary.Attribute(attr.Name.LocalName) == null)
                return false;
            if (attr.Value.ToLower() != secondary.Attribute(attr.Name.LocalName).Value.ToLower())
                return false;
        }
    }
    if (primary.HasElements) {
        if (primary.Elements().Count() != secondary.Elements().Count())
            return false;
        for (var i = 0; i <= primary.Elements().Count() - 1; i++) {
            if (XMLCompare(primary.Elements().Skip(i).Take(1).Single(), secondary.Elements().Skip(i).Take(1).Single()) == false)
                return false;
        }
    }
    return true;
}
于 2015-05-05T14:57:29.653 に答える
5

XML 文書の比較は複雑です。一部のツールについては、Google for xmldiff (Microsoft のソリューションもあります)。私はこれをいくつかの方法で解決しました。XSLT を使用して要素と属性を並べ替え (異なる順序で表示されることがあるため、気にしませんでした)、比較したくない属性を除外し、XML::Diffを使用しました。またはXML::SemanticDiff perl モジュールを使用するか、各ドキュメントを各要素と属性ごとに別の行にきれいに出力し、結果に対して Unix コマンド ライン diff を使用します。

于 2008-10-03T17:28:01.940 に答える
5

XMLUnitを試してください。このライブラリは、Java と .Net の両方で使用できます。

于 2011-11-23T13:45:37.867 に答える
3

XMLファイルの比較にExamXMLを使用しています。あなたはそれを試すことができます。著者のA7Softは、XMLファイルを比較するためのAPIも提供しています。

于 2009-11-16T14:20:41.140 に答える
3

これを行う別の方法は-

  1. 両方のファイルの内容を 2 つの異なる文字列に取得します。
  2. XSLT を使用して文字列を変換します (すべてを 2 つの新しい文字列にコピーするだけです)。これにより、要素の外側のすべてのスペースが確実に削除されます。これにより、2 つの新しい文字列が生成されます。
  3. 次に、2 つの文字列を互いに比較します。

これでは違いの正確な場所はわかりませんが、違いがあるかどうかだけを知りたい場合は、サードパーティのライブラリがなくても簡単に行うことができます。

于 2010-08-30T19:20:29.150 に答える
2

現在、子の順序を無視しているため、OP には関係ありませんが、コードのみのソリューションが必要な場合は、私がやや誤って開発したXmlSpecificationCompareを試すことができます。

于 2013-09-01T12:40:12.093 に答える