Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сортировка XML 
:(
    Опции темы
Vit
Дата 31.3.2008, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 1
Всего: 207



Требуется в общем-то тривиальная задача, но получающееся решение что-то меня не вдохновляет, какое-то некрасивое...



Требуется отсортировать сиблинги по значению атрибута. Поясню на примере

Итак есть XML типа
Код
<root>
  <child1 order="1">
    <subchildA order="1"/>
    <subchildB order="3"/>
    <subchildC order="2"/>
  </child1>
  <child2 order="3">
    <subchildD order="3"/>
    <subchildE order="1"/>
    <subchildF order="2"/>
  </child>
  <child3 order="2">
    <subchildG order="2"/>
    <subchildH order="3"/>
    <subchildJ order="1"/>
  </child3>
</root>


Из него надо получить XML в котором бы все сиблинги были отсортированы по значению аттрибута "Order", т.е. получить следующий результат:

Код
<root>
  <child1 order="1">
    <subchildA order="1"/>
    <subchildC order="2"/>
    <subchildB order="3"/>
  </child1>
  <child3 order="2">
    <subchildJ order="1"/>
    <subchildG order="2"/>
    <subchildH order="3"/>
  </child3>
  <child2 order="3">
    <subchildE order="1"/>
    <subchildF order="2"/>
    <subchildD order="3"/>
  </child>
</root>


Есть ли какое-то более или менее толковое решение?



--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Rififi
Дата 31.3.2008, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 5
Всего: 36



а нафига зачем нужна такая сортировка?
PM MAIL   Вверх
Vit
Дата 1.4.2008, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 1
Всего: 207



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


 
Цитата(Rififi @  31.3.2008,  13:31 Найти цитируемый пост)
а нафига зачем нужна такая сортировка? 


 smile Всегда страшно бесили подобные вопросы! Неужели трудно ответить на поставленный вопрос, или понимание зачем оно мне нужно как то приблизят к его решению? 

В данном случае требуется из одного XML файла получить другой. И точка... Спорить зачем это кому-то надо не требуется... Типа если кому-то надо получить из файла png файл pcx можно до хрипоты доказывать что png во много раз лучше pcx... но задание то от этого не меняется!


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Dblma
Дата 1.4.2008, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 6.11.2007
Где: Moscow

Репутация: нет
Всего: 1



Я не подскажу конкретного решения, но могу предложить глянуть LINQ.

http://msdn2.microsoft.com/ru-ru/library/b...960(en-us).aspx
PM MAIL ICQ   Вверх
mr.DUDA
Дата 1.4.2008, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Если делать руками, то так:
Код
using System;
using System.Xml;
using System.Collections.Generic;
using KVPair = System.Collections.Generic.KeyValuePair<int, int>;

class Program
{
    static void Main()
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(@"c:\1.xml");
        SortNodesRecursive(xml, "order");
        xml.Save(@"c:\2.xml");
    }

    static void SortNodesRecursive(XmlNode startNode, string attributeName)
    {
        // получаем индексы узлов и значения сортируемого атрибута
        List<KVPair> attrToIndex = new List<KVPair>();
        List<XmlNode> originalNodeList = new List<XmlNode>();
        for (int i = 0; i < startNode.ChildNodes.Count; i++)
        {
            originalNodeList.Add(startNode.ChildNodes[i]);

            // получаем значение атрибута по которому сортируем, как int
            XmlAttribute attr = startNode.ChildNodes[i].Attributes[attributeName];
            if (attr != null)
            {
                int order;
                if (int.TryParse(attr.Value, out order))
                {
                    attrToIndex.Add(new KVPair(order, i));
                    continue;
                }
            }

            // не прокатило, добавляем с позицией "в самом низу"
            attrToIndex.Add(new KVPair(int.MaxValue, i));
        }

        // сортируем по атрибуту
        attrToIndex.Sort(delegate(KVPair x, KVPair y)
        {
            return x.Key.CompareTo(y.Key);
        });

        // перестраиваем список узлов
        foreach (XmlNode node in originalNodeList)
            startNode.RemoveChild(node);
        foreach (KVPair p in attrToIndex)
            startNode.AppendChild(originalNodeList[p.Value]);

        // выполняем то же рекурсивно
        foreach (XmlNode node in startNode.ChildNodes)
            SortNodesRecursive(node, attributeName);
    }
}


З.Ы. кстати твой XML невалидный, исправил:
Код
<root>
  <child1 order="1">
    <subchildA order="1"/>
    <subchildB order="3"/>
    <subchildC order="2"/>
  </child1>
  <child2 order="3">
    <subchildD order="3"/>
    <subchildE order="1"/>
    <subchildF order="2"/>
  </child2>
  <child3 order="2">
    <subchildG order="2"/>
    <subchildH order="3"/>
    <subchildJ order="1"/>
  </child3>
</root>



--------------------
user posted image
PM MAIL WWW   Вверх
Rififi
Дата 1.4.2008, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 5
Всего: 36



Vit
Цитата
Всегда страшно бесили подобные вопросы

не волнуйся ты так, и береги нервы :gigi:

указанная задача решается с помощью .NET 3.5 и Linq to XML, или XSLT, или даже XQuery
первое проще всего, вот небольшой пример для подузла child1, остальное - по аналогии.

Код

XElement xdoc = XElement.Parse(
    @"<child1 order=""1"">
        <subchildA order=""1""/>
        <subchildB order=""3""/>
        <subchildC order=""2""/>
        </child1>"
    );


XElement sorted = new XElement("child1",
    from element in xdoc.Elements()
        orderby (string) element.Attribute("order")
        select element);


Это сообщение отредактировал(а) Rififi - 1.4.2008, 12:12
PM MAIL   Вверх
Vit
Дата 1.4.2008, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 1
Всего: 207



Цитата(mr.DUDA @  1.4.2008,  01:28 Найти цитируемый пост)
Если делать руками, то так:


Спасибо!

Цитата(mr.DUDA @  1.4.2008,  01:28 Найти цитируемый пост)
З.Ы. кстати твой XML невалидный, исправил:


Ну я ж не реальный XML дал, а так, то что от руки набросал, чтобы только смысл передать...

Цитата(Rififi @  1.4.2008,  03:08 Найти цитируемый пост)
указанная задача решается с помощью .NET 3.5 и Linq to XML, или XSLT, или даже XQuery
первое проще всего, вот небольшой пример для подузла child1, остальное - по аналогии.



.NET 3.5 - не подходит, задачу надо решить в 2.0


 Linq to XML, или XSLT, или даже XQuery - к сожалению не знаком с этими технологиями, но посмотрю.


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Rififi
Дата 1.4.2008, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 5
Всего: 36



Цитата
.NET 3.5 - не подходит, задачу надо решить в 2.0

а тебя не бесит, когда задается вопрос, а потом выясняется что вот этого нельзя, потому что у меня не то, а это вообще не так? smile:
PM MAIL   Вверх
mr.DUDA
Дата 1.4.2008, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Rififi, если явно не указано на какой платформе нужно решение, подразумевается наиболее широко распространённая на данный момент. Сейчас актуальнее всего 2.0, под 3.5 слишком мало софта. Будем считать тему платформы закрытой.

P.S. может быть можно то же самое сделать на XPath/XQuery, но с этими технологиями знаком слабо, поэтому привёл простейший вариант "в лоб"


M
mr.DUDA
P.S.(2) уважаемые all, просьба высказывать меньше эмоций в общих топиках



--------------------
user posted image
PM MAIL WWW   Вверх
Vit
Дата 3.4.2008, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 1
Всего: 207



mr.DUDA, спасибо!

Способ работает, пришлось сделать небольшую рехтовку под местные условия, но это мелочи. Большое спасибо!


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 3.4.2008, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



You are welcome  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
butalex11
Дата 27.12.2011, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 27.12.2011

Репутация: нет
Всего: нет



Здравствуйте! Очень нужна такая же сортировка, как у топикстартера, только нужно по текстовым аттрибутам, а не по int... Можете подсказать, пожалуйста, как изменить код, который написал mr.DUDA ? Заранее спасибо...

Это сообщение отредактировал(а) butalex11 - 27.12.2011, 13:40
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0790 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.