Как бы вы сравнили два XML-документа? - PullRequest
58 голосов
/ 03 октября 2008

Как часть базового класса для некоторого расширенного модульного тестирования, я пишу вспомогательную функцию, которая рекурсивно сравнивает узлы одного объекта XmlDocument с другим в C # (.NET). Некоторые требования этого:

  • Первым документом является источник , например как я хочу, чтобы XML-документ выглядел. Таким образом, второй - это тот, в котором я хочу найти различия, и он не должен содержать лишних узлов, отсутствующих в первом документе.
  • Должен выдать исключение, если обнаружено слишком много существенных различий, и это должно быть легко понято человеком, взглянувшим на описание.
  • Важен порядок дочерних элементов, атрибуты могут быть в любом порядке.
  • Некоторые атрибуты игнорируются; в частности xsi:schemaLocation и xmlns:xsi, хотя я бы хотел указать, какие из них.
  • Префиксы для пространств имен должны совпадать как по атрибутам, так и по элементам.
  • Пробел между элементами не имеет значения.
  • Элементы будут либо иметь дочерние элементы или InnerText, но не оба.

Пока я что-то записываю: кто-нибудь написал такой код и можно ли поделиться им здесь?

Кроме того, как бы вы назвали первый и второй документы? Я называю их «источником» и «целью», но это неправильно, поскольку source - это то, что я хочу, чтобы target выглядело как-то иначе, иначе я выбрасываю исключение .

Ответы [ 12 ]

0 голосов
/ 10 апреля 2018

Я написал этот сравнительный лист на основе XSLT 1.0, в котором вы сравниваете b.xml с входным xml, выводя различия элементов на входе, которых нет в b.xml.

https://github.com/sflynn1812/xslt-diff

0 голосов
/ 08 сентября 2017

На основе @Two Cents ответ и использование этой ссылки XMLSorting Я создал свой собственный XmlComparer

Сравнить программу XML

private static bool compareXML(XmlNode node, XmlNode comparenode)
    {

        if (node.Value != comparenode.Value)
            return false;

            if (node.Attributes.Count>0)
            {
                foreach (XmlAttribute parentnodeattribute in node.Attributes)
                {
                    string parentattributename = parentnodeattribute.Name;
                    string parentattributevalue = parentnodeattribute.Value;
                    if (parentattributevalue != comparenode.Attributes[parentattributename].Value)
                    {
                        return false;
                    }

                }

            }

          if(node.HasChildNodes)
            {
            sortXML(comparenode);
            if (node.ChildNodes.Count != comparenode.ChildNodes.Count)
                return false;
            for(int i=0; i<node.ChildNodes.Count;i++)
                {

                string name = node.ChildNodes[i].LocalName;
                if (compareXML(node.ChildNodes[i], comparenode.ChildNodes[i]) == false)
                    return false;
                }

            }



        return true;
    }

Программа сортировки XML

 private static void sortXML(XmlNode documentElement)
    {
        int i = 1;
        SortAttributes(documentElement.Attributes);
        SortElements(documentElement);
        foreach (XmlNode childNode in documentElement.ChildNodes)
        {
            sortXML(childNode);

        }
    }



  private static void SortElements(XmlNode rootNode)
    {



            for(int j = 0; j < rootNode.ChildNodes.Count; j++) {
                for (int i = 1; i < rootNode.ChildNodes.Count; i++)
                {
                    if (String.Compare(rootNode.ChildNodes[i].Name, rootNode.ChildNodes[1 - 1].Name) < 0)
                    {
                        rootNode.InsertBefore(rootNode.ChildNodes[i], rootNode.ChildNodes[i - 1]);

                    }


                }
            }
           // Console.WriteLine(j++);


    }
 private static void SortAttributes(XmlAttributeCollection attribCol)
    {
        if (attribCol == null)
            return;
        bool changed = true;
        while (changed)
        {
            changed = false;
            for (int i = 1; i < attribCol.Count; i++)
        {
                if (String.Compare(attribCol[i].Name, attribCol[i - 1].Name) < 0)
                {
                    //Replace
                    attribCol.InsertBefore(attribCol[i], attribCol[i - 1]);
                    changed = true;

                }
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...