powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Сравнение XElement'ов
17 сообщений из 17, страница 1 из 1
Сравнение XElement'ов
    #39935005
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток.
Прилетела интересная задача, два дня уже реализацию придумать не могу..)
Суть: есть две выборки данных, за определенный период, в xml.
Вот таких:
xEl1
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
<mainElement>
  <TIME_PERIOD TIME_START="08:00:00" TIME_END="12:00:00" />
  <STATUS Value="Отлично" Count="57" Weigth="189.774" Percent="76.721">
    <RESULT_PRODUCTION_LENGTH Value="100" Count="20" Weigth="129.76" Percent="52.459">
      <DRILLED Value="0" Count="20" Weigth="129.76" Percent="52.459" />
    </RESULT_PRODUCTION_LENGTH>
    <RESULT_PRODUCTION_LENGTH Value="25" Count="37" Weigth="60.014" Percent="24.262">
      <DRILLED Value="1" Count="36" Weigth="58.392" Percent="23.606" />
      <DRILLED Value="0" Count="1" Weigth="1.622" Percent="0.655" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Хорошо" Count="19" Weigth="30.818" Percent="12.459">
    <RESULT_PRODUCTION_LENGTH Value="25" Count="19" Weigth="30.818" Percent="12.459">
      <DEFFECT_GROUP Value="Группа '1'" Count="13" Weigth="21.086" Percent="8.524">
        <DEFFECT Value="Дефект '1'" Count="7" Weigth="11.354" Percent="4.59" />
        <DEFFECT Value="Дефект '2'" Count="6" Weigth="9.732" Percent="3.934" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '2'" Count="1" Weigth="1.622" Percent="0.655">
        <DEFFECT Value="Дефект '1'" Count="1" Weigth="1.622" Percent="0.655" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '3'" Count="4" Weigth="6.488" Percent="2.622">
        <DEFFECT Value="Дефект '1'" Count="2" Weigth="3.244" Percent="1.311" />
        <DEFFECT Value="Дефект '2'" Count="1" Weigth="1.622" Percent="0.655" />
        <DEFFECT Value="Дефект '3'" Count="1" Weigth="1.622" Percent="0.6557" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '4'" Count="1" Weigth="1.622" Percent="0.655">
        <DEFFECT Value="Дефект '1" Count="1" Weigth="1.622" Percent="0.655" />
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="19" Weigth="30.818" Percent="12.459" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Уд" Count="6" Weigth="24.33" Percent="9.836">
    <RESULT_PRODUCTION_LENGTH Value="100" Count="3" Weigth="19.464" Percent="7.868">
      <DEFFECT_GROUP Value="Группа '1'" Count="3" Weigth="19.464" Percent="7.868">
        <DEFFECT Value="Дефект 'Продир'" Count="1" Weigth="6.488" Percent="2.6229508196721221" />
        <DEFFECT Value="Дефект 'Вмятины'" Count="2" Weigth="12.976" Percent="5.2459016393442441" />
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="3" Weigth="19.464" Percent="7.868" />
    </RESULT_PRODUCTION_LENGTH>
    <RESULT_PRODUCTION_LENGTH Value="25" Count="3" Weigth="4.866" Percent="1.967">
      <DEFFECT_GROUP Value="Группа '3'" Count="2" Weigth="3.244" Percent="1.3114">
        <DEFFECT Value="Дефект 'Внутренний дефект (УЗК)'" Count="2" Weigth="3.244" Percent="1.311475409836061" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '4'" Count="1" Weigth="1.622" Percent="0.655">
        <DEFFECT Value="Дефект 'Кривизна по вертикали'" Count="1" Weigth="1.622" Percent="0.65573770491803052" />
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="3" Weigth="4.866" Percent="1.967" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Плохо" Count="3" Weigth="2.433" Percent="0.983">
    <RESULT_PRODUCTION_LENGTH Value="12,5" Count="3" Weigth="2.433" Percent="0.983">
      <DEFFECT_GROUP Value="Группа '2'" Count="3" Weigth="2.433" Percent="0.983">
        <DEFFECT Value="Дефект '2'" Count="1" Weigth="0.811" Percent="0.327" />
        <DEFFECT Value="Дефект '3'" Count="2" Weigth="1.622" Percent="0.655" />
      </DEFFECT_GROUP>
      <DRILLED Value="0" Count="2" Weigth="1.622" Percent="0.655" />
      <DRILLED Value="1" Count="1" Weigth="0.811" Percent="0.327" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
</mainElement>



xEl2
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
<mainElement>
  <TIME_PERIOD TIME_START="12:00:00" TIME_END="17:00:00" />
  <STATUS Value="Отлично" Count="58" Weigth="94.076" Percent="84.057">
    <RESULT_PRODUCTION_LENGTH Value="25" Count="58" Weigth="94.076" Percent="84.058">
      <DRILLED Value="1" Count="55" Weigth="89.21" Percent="79.71" />
      <DRILLED Value="0" Count="3" Weigth="4.866" Percent="4.348" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Хорошо" Count="8" Weigth="12.976" Percent="11.594">
    <RESULT_PRODUCTION_LENGTH Value="25" Count="8" Weigth="12.976" Percent="11.594">
      <DEFFECT_GROUP Value="Группа '1'" Count="2" Weigth="3.244" Percent="2.898">
        <DEFFECT Value="Дефект '2'" Count="2" Weigth="3.244" Percent="2.898" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '3'" Count="6" Weigth="9.732" Percent="8.695">
        <DEFFECT Value="Дефект '1'" Count="6" Weigth="9.732" Percent="8.695" />
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="8" Weigth="12.976" Percent="11.594" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Уд" Count="3" Weigth="4.866" Percent="4.347">
    <RESULT_PRODUCTION_LENGTH Value="25" Count="3" Weigth="4.866" Percent="4.347">
      <DEFFECT_GROUP Value="Группа '1'" Count="2" Weigth="3.244" Percent="2.898">
        <DEFFECT Value="Дефект '2'" Count="2" Weigth="3.244" Percent="2.898" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '3'" Count="1" Weigth="1.622" Percent="1.449">
        <DEFFECT Value="Дефект '1'" Count="1" Weigth="1.622" Percent="1.449" />
      </DEFFECT_GROUP>
      <DRILLED Value="0" Count="3" Weigth="4.866" Percent="4.347" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
</mainElement>



Необходимо сравнить их и сделать выборку вида
xElCompare
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
<mainElement>
  <TIME_PERIOD TIME_START_old="08:00:00" TIME_END_="12:00:00" TIME_START="12:00:00" TIME_END="17:00:00/>
  <STATUS Value="Отлично" Count="57" Weigth="189.774" Percent="76.721" Count="58" Weigth="94.076" Percent="84.057">
    <RESULT_PRODUCTION_LENGTH Value="100" Count="20" Weigth="129.76" Percent="52.459" Count="0" Weigth="0" Percent="0">
      <DRILLED Value="0" Count="20" Weigth="129.76" Percent="52.459" Count="0" Weigth="0" Percent="0"/>
    </RESULT_PRODUCTION_LENGTH>
    <RESULT_PRODUCTION_LENGTH Value="25" Count="37" Weigth="60.014" Percent="24.262" Count="58" Weigth="94.076" Percent="84.058">
      <DRILLED Value="1" Count="36" Weigth="58.392" Percent="23.606" Count="55" Weigth="89.21" Percent="79.71"/>
      <DRILLED Value="0" Count="1" Weigth="1.622" Percent="0.655" Count="3" Weigth="4.866" Percent="4.348"/>
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Хорошо" Count="19" Weigth="30.818" Percent="12.459" Count="8" Weigth="12.976" Percent="11.594">
    <RESULT_PRODUCTION_LENGTH Value="25" Count="19" Weigth="30.818" Percent="12.459" Count="8" Weigth="12.976" Percent="11.594">
      <DEFFECT_GROUP Value="Группа '1'" Count="13" Weigth="21.086" Percent="8.524" Count="2" Weigth="3.244" Percent="2.898">
        <DEFFECT Value="Дефект '1'" Count="7" Weigth="11.354" Percent="4.59" Count="0" Weigth="0" Percent="0"/>
        <DEFFECT Value="Дефект '2'" Count="6" Weigth="9.732" Percent="3.934" Count="2" Weigth="3.244" Percent="2.898"/>
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '2'" Count="1" Weigth="1.622" Percent="0.655" Count="0" Weigth="0" Percent="0">
        <DEFFECT Value="Дефект '1'" Count="1" Weigth="1.622" Percent="0.655"  Count="0" Weigth="0" Percent="0"/>
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '3'" Count="4" Weigth="6.488" Percent="2.622" Count="6" Weigth="9.732" Percent="8.695">
        <DEFFECT Value="Дефект '1'" Count="2" Weigth="3.244" Percent="1.311"  Count="6" Weigth="9.732" Percent="8.695" />
        <DEFFECT Value="Дефект '2'" Count="1" Weigth="1.622" Percent="0.655"  Count="0" Weigth="0" Percent="0"/>
        <DEFFECT Value="Дефект '3'" Count="1" Weigth="1.622" Percent="0.6557"  Count="0" Weigth="0" Percent="0"/>
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '4'" Count="1" Weigth="1.622" Percent="0.655" Count="0" Weigth="0" Percent="0">
        <DEFFECT Value="Дефект '1" Count="1" Weigth="1.622" Percent="0.655"  Count="0" Weigth="0" Percent="0"/>
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="19" Weigth="30.818" Percent="12.459" Count="8" Weigth="12.976" Percent="11.594"/>
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Уд" Count="6" Weigth="24.33" Percent="9.836" Count="3" Weigth="4.866" Percent="4.347">
    <RESULT_PRODUCTION_LENGTH Value="100" Count="3" Weigth="19.464" Percent="7.868" Count="0" Weigth="0" Percent="0">
      <DEFFECT_GROUP Value="Группа '1'" Count="3" Weigth="19.464" Percent="7.868" Count="0" Weigth="0" Percent="0">
        <DEFFECT Value="Дефект 'Продир'" Count="1" Weigth="6.488" Percent="2.6229508196721221" Count="0" Weigth="0" Percent="0" />
        <DEFFECT Value="Дефект 'Вмятины'" Count="2" Weigth="12.976" Percent="5.2459016393442441" Count="0" Weigth="0" Percent="0" />
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="3" Weigth="19.464" Percent="7.868" Count="0" Weigth="0" Percent="0"/>
    </RESULT_PRODUCTION_LENGTH>
    <RESULT_PRODUCTION_LENGTH Value="25" Count="3" Weigth="4.866" Percent="1.967" Count="3" Weigth="4.866" Percent="4.347>
	  <DEFFECT_GROUP Value="Группа '1'" Count="0" Weigth="0" Percent="0" Count="2" Weigth="3.244" Percent="2.898">
        <DEFFECT Value="Дефект '2'" Count="0" Weigth="0" Percent="0" Count="2" Weigth="3.244" Percent="2.898" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '3'" Count="2" Weigth="3.244" Percent="1.3114" Count="1" Weigth="1.622" Percent="1.449">
        <DEFFECT Value="Дефект '1'" Count="2" Weigth="3.244" Percent="1.311475409836061" Count="1" Weigth="1.622" Percent="1.449" />
      </DEFFECT_GROUP>
      <DEFFECT_GROUP Value="Группа '4'" Count="1" Weigth="1.622" Percent="0.655" Count="0" Weigth="0" Percent="0">
        <DEFFECT Value="Дефект 'Кривизна по вертикали'" Count="1" Weigth="1.622" Percent="0.65573770491803052" Count="0" Weigth="0" Percent="0" />
      </DEFFECT_GROUP>
      <DRILLED Value="1" Count="3" Weigth="4.866" Percent="1.967" />
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
  <STATUS Value="Плохо" Count="3" Weigth="2.433" Percent="0.983" Count="0" Weigth="0" Percent="0">
    <RESULT_PRODUCTION_LENGTH Value="12,5" Count="3" Weigth="2.433" Percent="0.983" Percent="0.983" Count="0" Weigth="0" Percent="0">
      <DEFFECT_GROUP Value="Группа '2'" Count="3" Weigth="2.433" Percent="0.983" Percent="0.983" Count="0" Weigth="0" Percent="0">
        <DEFFECT Value="Дефект '2'" Count="1" Weigth="0.811" Percent="0.327" Percent="0.983" Count="0" Weigth="0" Percent="0" />
        <DEFFECT Value="Дефект '3'" Count="2" Weigth="1.622" Percent="0.655"  Percent="0.983" Count="0" Weigth="0" Percent="0"/>
      </DEFFECT_GROUP>
      <DRILLED Value="0" Count="2" Weigth="1.622" Percent="0.655"  Percent="0.983" Count="0" Weigth="0" Percent="0"/>
      <DRILLED Value="1" Count="1" Weigth="0.811" Percent="0.327"  Percent="0.983" Count="0" Weigth="0" Percent="0"/>
    </RESULT_PRODUCTION_LENGTH>
  </STATUS>
</mainElement>



Или словами - если в каждом xml (xEl1, xEl2) есть XElement с одинаковым XAttribute("Value"), то добавить в результат этот XElement с атрибутами xEl1.XAttributes + xEl2.Attributes, если такой XElement встречается только в одном из xml, то добавить в результат этот XElement с исходными атрибутами, а недостающие забить нулями.

Есть ли у кого идеи как это реализовать?
З.Ы. Гугл мне предложил толко один достойный вариант https://stackoverflow.com/questions/37666529/linq-xelement-compare , но что-то под себя я его переделать не смог =)

Буду рад советам.
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935036
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В последнем вашем примере есть строка
Код: xml
1.
<STATUS Value="Отлично" Count="57" Weigth="189.774" Percent="76.721" Count="58" Weigth="94.076" Percent="84.057">


Что-то мне подсказывает, что в одном элементе два атрибута с одинаковым именем (например «Count») не уживутся. Тут надо или им имена как-то менять или с неймспейсами баловаться.
Или более по-другому задачу (и потребное решение) переформулировать.
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935045
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Colt, совершенно верно! Атрибуты должны быть с разными именами. Здесь так потому, что этот пример я собирал буквально в ручную, в блокноте, и менять имя в каждой ноде и каждом атрибуте ну такое себе..
Должно получиться, ну пусть так:
Код: xml
1.
STATUS Value="Отлично" Count_old="57" Weigth_old="189.774" Percent_old="76.721" Count_new="58" Weigth_new="94.076" Percent_new="84.057">
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935087
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: xml
1.
<STATUS Value="Отлично" Count_old="57" Weigth_old="189.774" Percent_old="76.721" Count_new="58" Weigth_new="94.076" Percent_new="84.057">


А почему атрибут «Value» представлен только в одном экземпляре? Он что, особенный? Где «Value_old» и «Value_new»?
Это я все к тому, что пока постановка задачи не совсем понятна (возможно только мне).
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935093
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну вот условно говоря сейчас делаю так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
internal class myData
internal class myData
        {
            public string name;
            public int count;
            public double weigth;
            public double percent;
        }

        private void compar(XElement xeOldData, XElement xeActualData)
        {
            XElement xeCompare = new XElement("mainElement");
            XElement xeElement = null;
            Dictionary<string, myData> oldDictionary;
            Dictionary<string, myData> newDictionary;// = fillDictionary(xeActualData);
            foreach (XElement element in xeOldData.Elements("STATUS"))
            {
                oldDictionary = fillDictionary(element);
                newDictionary = fillDictionary(
                   xeActualData.Elements("STATUS").AsEnumerable().Where(t =>
                   t.Attribute(element.Attribute("Value").Name).Value == element.Attribute("Value").Value).FirstOrDefault()
                   );
                xeElement = new XElement(element.Name);
                fillcompareData(ref xeCompare, oldDictionary, newDictionary);
            }
        }

        private void fillcompareData(ref XElement xeCompare, Dictionary<string, myData> oldDictionary, Dictionary<string, myData> newDictionary)
        {
            // По всем ключам старого списка
            foreach (string key in oldDictionary.Keys)
            {
                if (key != "") //Если ключ не пустой, здесь костыль
                {
                    var attributeNameOld = key;
                    var childAttributeValueOld = oldDictionary[key];
                    // если в новом списке есть такой ключ
                    if (newDictionary.ContainsKey(key))
                    {
                        var childAttributeValueNew = newDictionary[key];
                        xeCompare.Add(new XElement("Status",
                            new XAttribute("Value", attributeNameOld),
                            new XAttribute("Count_old", childAttributeValueOld.count),
                            new XAttribute("Weigth_old", childAttributeValueOld.weigth),
                            new XAttribute("Percent_old", childAttributeValueOld.percent),
                            new XAttribute("Count_new", childAttributeValueNew.count),
                            new XAttribute("Weigth_new", childAttributeValueNew.weigth),
                            new XAttribute("Percent_new", childAttributeValueNew.percent)
                            ));
                    }
                    // если такого ключа в новом списке нет, добавляем в результат
                    else
                    {
                        xeCompare.Add(new XElement("Status",
                            new XAttribute("Value", attributeNameOld),
                            new XAttribute("Count_old", childAttributeValueOld.count),
                            new XAttribute("Weigth_old", childAttributeValueOld.weigth),
                            new XAttribute("Percent_old", childAttributeValueOld.percent),
                            new XAttribute("Count_new", 0),
                            new XAttribute("Weigth_new", 0),
                            new XAttribute("Percent_new", 0)
                            ));
                    }
                }
            }
            foreach (string key in newDictionary.Keys)
            {
                if (key != "") //Если ключ не пустой, здесь костыль
                {
                    var attributeNameOld = key;
                    var childAttributeValueOld = newDictionary[key];
                    if (!oldDictionary.ContainsKey(key))
                    {
                        xeCompare.Add(new XElement("Status",
                            new XAttribute("Value", attributeNameOld),
                            new XAttribute("Count_old", 0),
                            new XAttribute("Weigth_old", 0),
                            new XAttribute("Percent_old", 0),
                            new XAttribute("Count_new", childAttributeValueOld.count),
                            new XAttribute("Weigth_new", childAttributeValueOld.weigth),
                            new XAttribute("Percent_new", childAttributeValueOld.percent)
                            ));
                    }
                }
            }
            //return xeCompare;
        }
        private Dictionary<string, myData> fillDictionary(XElement xeData)
        {
            Dictionary<string, myData> dictionary = new Dictionary<string, myData>();           
            try
            {
                myData newAtributes = new myData();
                newAtributes.name = xeData.Attribute("Value").Value;
                newAtributes.count = Convert.ToInt32(xeData.Attribute("Count").Value);
                newAtributes.weigth = Math.Round(double.Parse(xeData.Attribute("Weigth").Value, CultureInfo.InvariantCulture), 3);
                newAtributes.percent = Math.Round(double.Parse(xeData.Attribute("Percent").Value, CultureInfo.InvariantCulture), 3);

                dictionary.Add(xeData.Attribute("Value").Value, newAtributes);
                return dictionary;
            }
            catch (NullReferenceException) //Для несуществующего элемента
            {
                myData newAtributes = new myData();
                newAtributes.name = "";
                newAtributes.count = 0;
                newAtributes.weigth = 0;
                newAtributes.percent = 0;

                dictionary.Add("", newAtributes);
                return dictionary;
            }
        }



И получаю
Код: xml
1.
2.
3.
4.
5.
6.
<mainElement>
  <Status Value="Отлично" Count_old="57" Weigth_old="189.774" Percent_old="76.721" Count_new="58" Weigth_new="94.076" Percent_new="84.058" />
  <Status Value="Хорошо" Count_old="19" Weigth_old="30.818" Percent_old="12.459" Count_new="8" Weigth_new="12.976" Percent_new="11.594" />
  <Status Value="Уд" Count_old="6" Weigth_old="24.33" Percent_old="9.836" Count_new="3" Weigth_new="4.866" Percent_new="4.348" />
  <Status Value="Плохо" Count_old="3" Weigth_old="2.433" Percent_old="0.984" Count_new="0" Weigth_new="0" Percent_new="0" />
</mainElement>


Но если поменяю выборки местами (xEl2, xEl1), то уже
Код: xml
1.
2.
3.
4.
5.
6.
<mainElement>
  <Status Value="Отлично" Count_old="58" Weigth_old="94.076" Percent_old="84.058" Count_new="57" Weigth_new="189.774" Percent_new="76.721" />
  <Status Value="Хорошо" Count_old="8" Weigth_old="12.976" Percent_old="11.594" Count_new="19" Weigth_new="30.818" Percent_new="12.459" />
  <Status Value="Уд" Count_old="3" Weigth_old="4.866" Percent_old="4.348" Count_new="6" Weigth_new="24.33" Percent_new="9.836" />
</mainElement>
Последнего элемента нет.
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935117
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Colt
А почему атрибут «Value» представлен только в одном экземпляре? Он что, особенный?

Извините, невнимательно прочитал ТЗ, он действительно особенный
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935128
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Colt, возможно, для того чтобы была более ясна картина, в конечном итоге пользователю будет предоставлена такого рода сводная таблица (всю таблицу забивать уж не стал, думаю общая идея понятна):
Сводная таблица
- - период1 - - период2 -Статус кол-во масса проценткол-во масса процентОтлично57189.774 48.45 5894.07640.02Хорошо1930.81816.15812.9765.52Уд62.4335.134.8662.07Плохо32.4332.55000-Отлично57 18.774 48.45 58 94.076 40.02длина120 129.76 17 0 0 0drill20 129.76 17 0 0 0длина237 60.014 31.45 58 94.076 40.02drill36 58.392 30.6 55 89.21 37.95drill1 1 1.622 0.85 3 4.866 2.07-Хорошо19 30.818 16.15 8 12.976 5.52длина119 30.818 16.15 8 12.976 5.52-Уддлина1длина2-Плоходлина1длина2
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935142
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может у вас есть xsd-схема файлов (или вы ее сможете сами сделать)?
Это к тому, чтобы было четко понятно какие элементы и атрибуты встречаются и какую структуру вложенности они подразумевают.
Возможно это облегчит понимание ТЗ и создание решения.

Что-то у меня крутиться мысля провернуть это через xslt-преобразование или через LINQ. Но, может, и зря крутиться, может это проще делать как-то по-другому...
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935164
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Colt, да, конечно:
xsd
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="mainElement" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="mainElement" msdata:IsDataSet="true" msdata:Locale="en-US">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="TIME_PERIOD">
          <xs:complexType>
            <xs:attribute name="TIME_START" type="xs:string" />
            <xs:attribute name="TIME_END" type="xs:string" />
          </xs:complexType>
        </xs:element>
        <xs:element name="STATUS">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="RESULT_PRODUCTION_LENGTH" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="DEFFECT_GROUP" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="DEFFECT" minOccurs="0" maxOccurs="unbounded">
                            <xs:complexType>
                              <xs:attribute name="Value" type="xs:string" />
                              <xs:attribute name="Count" type="xs:int" />
                              <xs:attribute name="Weigth" type="xs:double" />
                              <xs:attribute name="Percent" type="xs:double" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="Value" type="xs:string" />
                        <xs:attribute name="Count" type="xs:int" />
                        <xs:attribute name="Weigth" type="xs:double" />
                        <xs:attribute name="Percent" type="xs:double" />
                      </xs:complexType>
                    </xs:element>
                    <xs:element name="DRILLED" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:attribute name="Value" type="xs:string" />
                        <xs:attribute name="Count" type="xs:string" />
                        <xs:attribute name="Weigth" type="xs:string" />
                        <xs:attribute name="Percent" type="xs:string" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="Value" type="xs:string" />
                  <xs:attribute name="Count" type="xs:string" />
                  <xs:attribute name="Weigth" type="xs:string" />
                  <xs:attribute name="Percent" type="xs:string" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="Value" type="xs:string" />
            <xs:attribute name="Count" type="xs:string" />
            <xs:attribute name="Weigth" type="xs:string" />
            <xs:attribute name="Percent" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>




По сути, через Linq сейчас и пытаюсь что-то сделать.
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935209
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Несколько вопросов по схеме:
1. Элемент TIME_PERIOD действительно может встречаться несколько раз (причем не обязательно в начале файла) или даже вовсе отсутствовать (согласно схеме именно так)? Или он должен быть ровно один раз, причем в начале?
2. Все атрибуты описаны как необязательные, это действительно так, или они все-таки обязательно должны быть?
3. Для элементов DEFFECT_GROUP и DEFFECT типы атрибутов описаны как xs:string, xs:int и xs:double, а для элементов STATUS, RESULT_PRODUCTION_LENGTH и DRILLED они все указаны как xs:string. Почему?

Может это и не принципиально, но хотелось бы внести ясность
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935225
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Colt,
Colt1. Элемент TIME_PERIOD действительно может встречаться несколько раз (причем не обязательно в начале файла) или даже вовсе отсутствовать (согласно схеме именно так)? Или он должен быть ровно один раз, причем в начале?
Согласно схеме это так, но по факту, TIME_PERIOD всегда будет только один раз, и только в начале.
Colt2. Все атрибуты описаны как необязательные, это действительно так, или они все-таки обязательно должны быть?
Да, совершенно верно, все элементы не обязательные. По факту, всегда будут только mainElement и TIME_PERIOD. Все остальные могут как отсутствовать, так и повторяться несколько раз. По факту, STATUS может повториться не более 4 раз, RESULT_PRODUCTION_LENGTH не более 3 раз, элементы DEFFECT_GROUP и DEFFECT - много, несколько десятков повторений запросто.
Colt3. Для элементов DEFFECT_GROUP и DEFFECT типы атрибутов описаны как xs:string, xs:int и xs:double, а для элементов STATUS, RESULT_PRODUCTION_LENGTH и DRILLED они все указаны как xs:string. Почему?
Такс, я - косяк. Каюсь, как-то пропустил не заметил string (хотя вроде менял...). Все атрибуты для всех элементов
Код: xml
1.
2.
3.
4.
<xs:attribute name="Value" type="xs:string" />
<xs:attribute name="Count" type="xs:int" />
<xs:attribute name="Weigth" type="xs:double" />
<xs:attribute name="Percent" type="xs:double" />
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935230
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mozgen

Colt2. Все атрибуты описаны как необязательные, это действительно так, или они все-таки обязательно должны быть?

Да, совершенно верно, все элементы не обязательные.
Я тут уточнял про обязательность атрибутов, а не элементов
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935268
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Чур, не плеваться (я сам в LINQ очень сильно не доцент), наверное, можно было сделать как-то более просто и красиво, но пока так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xml1 = XDocument.Load("Input1.xml");
            XDocument xml2 = XDocument.Load("Input2.xml");
            XDocument res = GetResult(xml1, xml2);
            res.Save("Output.xml");
        }

        static readonly IEnumerable<XElement> EmptyList = new XElement[] { };

        static XDocument GetResult(XDocument xml1, XDocument xml2)
        {
            IEnumerable<string> GetKeys(IEnumerable<XElement> ls1, IEnumerable<XElement> ls2)
            {
                return
                    ls1.Select(x => x.Attribute("Value").Value)
                    .Union(ls2.Select(x => x.Attribute("Value").Value))
                    .Distinct().OrderBy(x => x);
            }
            XElement FindOnKey(string key, IEnumerable<XElement> ls)
            {
                return ls.Where(x => x.Attribute("Value").Value == key).FirstOrDefault();
            }
            XElement GetTimePeriod(XElement root1, XElement root2)
            {
                XElement x1 = root1.Element("TIME_PERIOD");
                XElement x2 = root2.Element("TIME_PERIOD");
                return
                    new XElement(
                        "TIME_PERIOD",
                        new XAttribute("TIME_START_old", x1.Attribute("TIME_START").Value),
                        new XAttribute("TIME_START_new", x2.Attribute("TIME_START").Value),
                        new XAttribute("TIME_END_old", x1.Attribute("TIME_END").Value),
                        new XAttribute("TIME_END_new", x2.Attribute("TIME_END").Value)
                        );
            }
            XElement GetStatus(string key, XElement root1, XElement root2)
            {
                XElement x1 = FindOnKey(key, root1.Elements("STATUS"));
                XElement x2 = FindOnKey(key, root2.Elements("STATUS"));
                IEnumerable<string> Keys = GetKeys(
                    x1?.Elements("RESULT_PRODUCTION_LENGTH") ?? EmptyList,
                    x2?.Elements("RESULT_PRODUCTION_LENGTH") ?? EmptyList);
                return
                    new XElement(
                        "STATUS",
                        new XAttribute("Value", key),
                        new XAttribute("Count_old", x1?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Count_new", x2?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Weigth_old", x1?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Weigth_new", x2?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Percent_old", x1?.Attribute("Percent")?.Value ?? "0"),
                        new XAttribute("Percent_new", x2?.Attribute("Percent")?.Value ?? "0"),
                        Keys.Select(x => GetResultProductionLength(x, x1, x2))
                        );
            }
            XElement GetResultProductionLength(string key, XElement root1, XElement root2)
            {
                XElement x1 = FindOnKey(key, root1?.Elements("RESULT_PRODUCTION_LENGTH") ?? EmptyList);
                XElement x2 = FindOnKey(key, root2?.Elements("RESULT_PRODUCTION_LENGTH") ?? EmptyList);
                IEnumerable<string> Keys1 = GetKeys(
                    x1?.Elements("DEFFECT_GROUP") ?? EmptyList,
                    x2?.Elements("DEFFECT_GROUP") ?? EmptyList);
                IEnumerable<string> Keys2 = GetKeys(
                    x1?.Elements("DRILLED") ?? EmptyList,
                    x2?.Elements("DRILLED") ?? EmptyList);
                return
                    new XElement(
                        "RESULT_PRODUCTION_LENGTH",
                        new XAttribute("Value", key),
                        new XAttribute("Count_old", x1?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Count_new", x2?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Weigth_old", x1?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Weigth_new", x2?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Percent_old", x1?.Attribute("Percent")?.Value ?? "0"),
                        new XAttribute("Percent_new", x2?.Attribute("Percent")?.Value ?? "0"),
                        Keys1.Select(x => GetDeffectGroup(x, x1, x2)),
                        Keys2.Select(x => GetDrilled(x, x1, x2))
                        );
            }
            XElement GetDeffectGroup(string key, XElement root1, XElement root2)
            {
                XElement x1 = FindOnKey(key, root1?.Elements("DEFFECT_GROUP") ?? EmptyList);
                XElement x2 = FindOnKey(key, root2?.Elements("DEFFECT_GROUP") ?? EmptyList);
                IEnumerable<string> Keys = GetKeys(
                    x1?.Elements("DEFFECT") ?? EmptyList,
                    x2?.Elements("DEFFECT") ?? EmptyList);
                return
                    new XElement(
                        "DEFFECT_GROUP",
                        new XAttribute("Value", key),
                        new XAttribute("Count_old", x1?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Count_new", x2?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Weigth_old", x1?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Weigth_new", x2?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Percent_old", x1?.Attribute("Percent")?.Value ?? "0"),
                        new XAttribute("Percent_new", x2?.Attribute("Percent")?.Value ?? "0"),
                        Keys.Select(x => GetDeffect(x, x1, x2))
                        );
            }
            XElement GetDeffect(string key, XElement root1, XElement root2)
            {
                XElement x1 = FindOnKey(key, root1?.Elements("DEFFECT") ?? EmptyList);
                XElement x2 = FindOnKey(key, root2?.Elements("DEFFECT") ?? EmptyList);
                return
                    new XElement(
                        "DEFFECT",
                        new XAttribute("Value", key),
                        new XAttribute("Count_old", x1?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Count_new", x2?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Weigth_old", x1?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Weigth_new", x2?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Percent_old", x1?.Attribute("Percent")?.Value ?? "0"),
                        new XAttribute("Percent_new", x2?.Attribute("Percent")?.Value ?? "0")
                        );
            }
            XElement GetDrilled(string key, XElement root1, XElement root2)
            {
                XElement x1 = FindOnKey(key, root1?.Elements("DRILLED") ?? EmptyList);
                XElement x2 = FindOnKey(key, root2?.Elements("DRILLED") ?? EmptyList);
                return
                    new XElement(
                        "DRILLED",
                        new XAttribute("Value", key),
                        new XAttribute("Count_old", x1?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Count_new", x2?.Attribute("Count")?.Value ?? "0"),
                        new XAttribute("Weigth_old", x1?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Weigth_new", x2?.Attribute("Weigth")?.Value ?? "0"),
                        new XAttribute("Percent_old", x1?.Attribute("Percent")?.Value ?? "0"),
                        new XAttribute("Percent_new", x2?.Attribute("Percent")?.Value ?? "0")
                        );
            }

            IEnumerable<string> StatusKeys = GetKeys(xml1.Root.Elements("STATUS"), xml2.Root.Elements("STATUS"));
            return
                new XDocument(
                    new XDeclaration("1.0", "utf-8", null),
                    new XElement(
                        "mainElement",
                        GetTimePeriod(xml1.Root, xml2.Root),
                        StatusKeys.Select(x => GetStatus(x, xml1.Root, xml2.Root))
                        )
                    );
        }
    }
}


...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935795
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Colt,
Хм. Премного благодарствую. Все (как регулярно и случается) намного проще и логичнее моих потугов =)
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935797
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А не проще было бы сделать классы (тем более раз уж есть xsd), XML десериализовать в эти классы, для классов реализовать компараторы, ну и потом сравнивать коллекции/экземпляры этих классов, а не возиться со сравнением значений атрибутов-узлов?
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935836
mozgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сон Веры Павловны, в чем-то да, вы правы, было бы проще. Но, честно говоря, чет гонять постоянно xml в классы и обратно, ну такое себе. Нет, я не спорю, так даже удобнее, возможно. Но интерес представлял именно вопрос сравнения двух XElement.
...
Рейтинг: 0 / 0
Сравнение XElement'ов
    #39935837
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mozgen
Но, честно говоря, чет гонять постоянно xml в классы и обратно, ну такое себе.

XmlSerializer.Deserialize
В 99% случаев эта десериализация умещается в 2-3 строки кода.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Сравнение XElement'ов
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]