Подтвердить что ты не робот

Сравнение Xml в С#

Я пытаюсь сравнить два файла Xml с помощью кода С#. Я хочу игнорировать различия в синтаксисе Xml (т.е. Имена префикса). Для этого я использую Microsoft XML Diff и Patch С# API. Он работает для некоторых Xml, но я не смог найти способ настроить его для работы со следующими двумя Xml:

XML A:

<root xmlns:ns="http://myNs">
  <ns:child>1</ns:child>
</root>

XML B:

<root>
  <child xmlns="http://myNs">1</child>
</root>

Мои вопросы:

  • Правильно ли, что эти два xml семантически равны (или изоморфны)?
  • Можно ли настроить Microsoft Diff и Patch API для поддержки?
  • Есть ли для этого другие утилиты С#?
4b9b3361

Ответ 1

У меня есть ответ Мартина Хоннен в XML и форум MSDN.NET Framework. Короче говоря, он предлагает использовать функцию XQuery 1.0 с глубокой равностью и предоставляет некоторые реализации С#. Кажется, работает.

Ответ 2

Документы изоморфны, как показано в приведенной ниже программе. Я думаю, если вы используете XmlDiffOptions.IgnoreNamespaces и XmlDiffOptions.IgnorePrefixes для настройки Microsoft.XmlDiffPatch.XmlDiff, вы получите нужный результат.

using System.Linq;
using System.Xml.Linq;
namespace SO_794331
{
    class Program
    {
        static void Main(string[] args)
        {
            var docA = XDocument.Parse(
                @"<root xmlns:ns=""http://myNs""><ns:child>1</ns:child></root>");
            var docB = XDocument.Parse(
                @"<root><child xmlns=""http://myNs"">1</child></root>");

            var rootNameA = docA.Root.Name;
            var rootNameB = docB.Root.Name;
            var equalRootNames = rootNameB.Equals(rootNameA);

            var descendantsA = docA.Root.Descendants();
            var descendantsB = docB.Root.Descendants();
            for (int i = 0; i < descendantsA.Count(); i++)
            {
                var descendantA = descendantsA.ElementAt(i);
                var descendantB = descendantsB.ElementAt(i);
                var equalChildNames = descendantA.Name.Equals(descendantB.Name);

                var valueA = descendantA.Value;
                var valueB = descendantB.Value;
                var equalValues = valueA.Equals(valueB);
            }
        }
    }
}

Ответ 3

Я знаю, что вы сосредоточены не на модульных тестах, но XMLUnit может сравнивать два файла XML, и я думаю, что это способный решить ваш пример. Возможно, вы могли бы взглянуть на код и выяснить свое решение.

Ответ 4

Может возникнуть идея загрузить экземпляры XmlDocument из каждого xml файла и вместо этого сравнить XML DOM? Обеспечение правильной проверки выполняется для каждого, что должно дать вам общее основание для сравнения и должно допускать стандартную отчетность о различиях. Возможно даже возможность обновлять один от другого с помощью дельта.

Ответ 5

Эти документы не являются семантически эквивалентными. Элемент верхнего уровня первого находится в пространстве имен http://myNS, а элемент верхнего уровня второго - в пространстве имен по умолчанию.

Детские элементы двух документов эквивалентны. Но сами документы не являются.

Edit:

Там есть мир различий между xmls:ns='http://myNS' и xmlns='http://myNS', который, как мне кажется, упустил. Во всяком случае, эти документы семантически эквивалентны, и я просто ошибаюсь.