Модераторы: diadiavova
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка числовых результатов, Нетривиальный алгоритм 
V
    Опции темы
davidoffpk
Дата 1.3.2010, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Есть файл следующего вида, отражающий доходы и расходы человека по месяцам:

Код

<Name1>
<Налог>
<Месяц 1>
<Доход> 6 </Доход>
<Расход> 4 </Расход>
<Разница> 2 </Разница>
</Месяц 1>
<Месяц 2>
<Доход> 7 </Доход>
<Расход> 4 </Расход>
<Разница> 3 </Разница>
</Месяц 2>
<Месяц 3>
<Доход> 6 </Доход>
<Расход> 10 </Расход>
<Разница> -4 </Разница>
</Месяц 3>
<Месяц 5>
<Доход> 5 </Доход>
<Расход> 4 </Расход>
<Разница> 1 </Разница>
</Месяц 5>
<Месяц 6>
<Доход> 2 </Доход>
<Расход> 2 </Расход>
<Разница> 0 </Разница>
</Месяц 6>
</Налог>
</Name1>
<Name2>
...............
</Name2>


Проблема заключается в том, что отрицательной разницы за месяц формально быть не может. Нужно скомпенсировать отрицательные разницы за счет доходов в те месяца, где разница положительная. То есть если разница в 3-м месяце "-4", то нужно вместо отрицательного числа (-4) поставить "0" и вычесть "4" из доходов первого и второго месяца, чтобы разница там оставалась неотрицательной. Должно быть например так:
 
Код

<Name1>
<Налог>
<Месяц 1>
<Доход> 4 </Доход> <!-- 6+(-2) -->
<Расход> 4 </Расход>
<Разница> 0 </Разница>
</Месяц 1>
<Месяц 2>
<Доход> 5 </Доход> <!-- 7+(-2) -->
<Расход> 4 </Расход>
<Разница> 1 </Разница>
</Месяц 2>
<Месяц 3>
<Доход> 10 </Доход> <!-- 6+4 -->
<Расход> 10 </Расход>
<Разница> 0 </Разница> <!-- (-4) разбито на (-2) к доходам 1-го месяца и (-2) к доходам 2-го месяца = -->
</Месяц 3>
<Месяц 5>
<Доход> 5 </Доход>
<Расход> 4 </Расход>
<Разница> 1 </Разница>
</Месяц 5>
<Месяц 6>
<Доход> 2 </Доход>
<Расход> 2 </Расход>
<Разница> 0 </Разница>
</Месяц 6>
</Налог>
</Name1>
<Name2>
...............
</Name2>


Помогите придумать xslt преобразование, плиз! 

Это сообщение отредактировал(а) davidoffpk - 1.3.2010, 12:09
PM MAIL   Вверх
Zloxa
Дата 1.3.2010, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(davidoffpk @  1.3.2010,  12:07 Найти цитируемый пост)
придумать xslt преобразование

тебе не кажется, что "вычисление" и "расчет" выходят за пределы понятия трансофрмация?


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
diadiavova
Дата 1.3.2010, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

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



Цитата(davidoffpk @  1.3.2010,  12:07 Найти цитируемый пост)
Нужно скомпенсировать отрицательные разницы за счет доходов в те месяца, где разница положительная.

А если она отрицательная уже в первом месяце, или, например, доходов предшествующих месяцев недостаточно для компенсации? Вообще-то я думаю, что XSLT - не подходит для решения подобных задач, может и возможно решить задачу с помощью XSLT, но решение будет неоправданно сложным.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
davidoffpk
Дата 1.3.2010, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(diadiavova @ 1.3.2010,  12:20)
А если она отрицательная уже в первом месяце, или, например, доходов предшествующих месяцев недостаточно для компенсации? Вообще-то я думаю, что XSLT - не подходит для решения подобных задач, может и возможно решить задачу с помощью XSLT, но решение будет неоправданно сложным.

Такого быть не может. В файл попадают лишь те люди, отрицательную разницу которых можно скомпенсировать.

Да вот и мне уже тоже кажется, что слишком сложно)) Просто тогда наверное нужно: 

1)либо обрабатывать xml, скажем, С/С++, а я не знаком с этими методами... 
2)либо обрабатывать xml просто как текстовый документ, что в силу объема тоже не очень просто. Потеряется структура.
3)либо импортировать xml в MS Access или Excel.

Я в программировании новичок. Посоветуйте, как бы вы решали эту задачу? 
PM MAIL   Вверх
diadiavova
Дата 1.3.2010, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

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



Цитата(davidoffpk @  1.3.2010,  12:58 Найти цитируемый пост)
Посоветуйте, как бы вы решали эту задачу?  

Исключительно при помощи какого-нибудь, известного мне, языка программирования общего назначения. Хотя, если это недоступно, то возможно вариант
Цитата(davidoffpk @  1.3.2010,  12:58 Найти цитируемый пост)
импортировать xml в MS Access или Excel

тоже прокатит. Единственная оговорка: в XML имена элементов не могут содержать пробелов, так что на элементы типа
Код
<Месяц 1>
будет ругаться любая программа.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Zloxa
Дата 1.3.2010, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(davidoffpk @  1.3.2010,  12:07 Найти цитируемый пост)
<Месяц 1>

Откуда берутся такие XML?
Этот XML not wellformated, его XSLем не возьмешь по всякому.
Цитата(davidoffpk @  1.3.2010,  12:58 Найти цитируемый пост)
как бы вы решали эту задачу?  

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


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
davidoffpk
Дата 1.3.2010, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Zloxa @ 1.3.2010,  13:15)
Откуда берутся такие XML?
Этот XML not wellformated, его XSLем не возьмешь по всякому.

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

Такую XML я написал быстренько от руки и забыл про пробелы. В реальном XML структура значительно сложнее. 

С ораклом я пока не общался, да и SQL знаю пока весьма и весьма посредственно. Я пробовал импортировать все в Access, но там теряется структура документа из-за того, что она сложнее чем я описал в примере. Придется вручную разбивать это по таблицам, потому я и хотел обойтись возможностями только xslt.

Если не сложно, напишите подробнее про обработку ораклом и про этот волшебный запрос) Я ближайшее время буду изучать оракл и может мне это поможет. Заранее спасибо! 
PM MAIL   Вверх
Zloxa
Дата 1.3.2010, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(davidoffpk @  1.3.2010,  14:08 Найти цитируемый пост)
Если не сложно

Мне не настолько сложно написать этот запрос, насколько Вам сложно будет его понять.
Как бы там ни было, спасибо за интересную задачу. Не смотря, на то, что такая задача интересна может быть лишь задротам вроде меня, да LKhiger.
Что интересного в этой задаче? Мне впервые довелось одновременно использовать регекспы, xml и модель. Решение получилось исключительно декларативное, ни одного итерационного оператора. В реальной жизне, с реальными задачами,  таку хрень практически не встретишь.
Код

SQL> with src as (select '<Name1>
  2  <Налог>
  3  <Месяц 1>
  4  <Доход> 6 </Доход>
  5  <Расход> 4 </Расход>
  6  <Разница> 2 </Разница>
  7  </Месяц 1>
  8  <Месяц 2>
  9  <Доход> 7 </Доход>
 10  <Расход> 4 </Расход>
 11  <Разница> 3 </Разница>
 12  </Месяц 2>
 13  <Месяц 3>
 14  <Доход> 6 </Доход>
 15  <Расход> 10 </Расход>
 16  <Разница> -4 </Разница>
 17  </Месяц 3>
 18  <Месяц 5>
 19  <Доход> 5 </Доход>
 20  <Расход> 4 </Расход>
 21  <Разница> 1 </Разница>
 22  </Месяц 5>
 23  <Месяц 6>
 24  <Доход> 2 </Доход>
 25  <Расход> 1 </Расход>
 26  <Разница> 0 </Разница>
 27  </Месяц 6>
 28  </Налог>
 29  </Name1>' SRC
 30    from dual
 31  )
 32  , xml as (select
 33               regexp_replace(
 34                   regexp_replace(
 35                       src
 36                       ,'<Месяц\s*(\d+)>([^$]*?)</Месяц\s*\d+>'
 37                       ,'<Месяц num = "\1">\2</Месяц>'
 38                    )
 39                    ,'<Name\s*(\d+)>([^$]*?)</Name\s*\d+>'
 40                    ,'<Name num = "\1">\2</Name>'
 41              ) xml
 42        from src
 43  )
 44  ,result as(
 45    select *
 46      from xml
 47           ,table(xmlsequence(XMLType(xml).Extract('/Name/Налог/Месяц'))) t
 48    model partition by (ExtractValue(XMLType(xml),'/Name/@num') Name)
 49          dimension by  (row_number() over (order by to_number(extractValue(value(t),'/Месяц/@num') )) ord_num)
 50          measures (extractValue(value(t),'/Месяц/@num') month
 51                    ,to_number(ExtractValue(value(t),'/Месяц/Доход')) income
 52                    ,to_number(ExtractValue(value(t),'/Месяц/Расход')) outcome
 53                    , 0 dif
 54                    , 0 compensation
 55                    )
 56          rules (
 57                 dif[any] = income[cv()]-outcome[cv()]
 58                 ,income[any] order by ord_num desc = income[cv()]-least(0,dif[cv()])
 59                 ,compensation[any] order by ord_num desc = case when dif[cv()] < 0  then dif[cv()] + nvl(compensation[cv()+1],0)
 60                                                                 when dif[cv()] > 0 and compensation[cv()+1] < 0 then compensation[cv()+1] + least(dif[cv()],- compensation[cv()+1])
 61                                                                 else 0
 62                                                            end
 63                 ,outcome[any] order by ord_num desc = outcome[cv()] + least(nvl(-compensation[cv()+1],0),greatest(dif[cv()],0))
 64          )
 65    )
 66  ,resultXML as (
 67    select XMLElement("Name"
 68                      ,XMLAttributes(name as "num")
 69                      ,XMLElement("Налог"
 70                                  ,XMLAgg(
 71                                          XMLElement("Месяц"
 72                                                     ,XMLAttributes(month as "num")
 73                                                    ,XMLForest(
 74                                                       income as "Доход"
 75                                                       ,outcome as "Расход"
 76                                                       ,income-outcome as "Разница"
 77                                                     )
 78                                                    )
 79                                          )
 80                                  )
 81                      ).extract('*').getStringVal() xml
 82      from result
 83    group by name
 84   )
 85  select
 86    regexp_replace(
 87         regexp_replace(
 88             xml
 89             ,'<Месяц\s+num="(\d+)">([^$]*?)</Месяц>'
 90             ,'<Месяц \1>\2</Месяц \1>'
 91         )
 92         ,'<Name\s+num="(\d+)">([^$]*?)</Name>'
 93         ,'<Name\1>\2</Name\1>'
 94   ) result
 95  from
 96  resultxml
 97  ;
 
RESULT
--------------------------------------------------------------------------------
<Name1>
  <Налог>
    <Месяц 1>
      <Доход>6</Доход>
      <Расход>5</Расход>
      <Разница>1</Разница>
    </Месяц 1>
    <Месяц 2>
      <Доход>7</Доход>
      <Расход>7</Расход>
      <Разница>0</Разница>
    </Месяц 2>
    <Месяц 3>
      <Доход>10</Доход>
      <Расход>10</Расход>
      <Разница>0</Разница>
    </Месяц 3>
    <Месяц 6>
      <Доход>2</Доход>
      <Расход>1</Расход>
      <Разница>1</Разница>
    </Месяц 6>
    <Месяц 5>
      <Доход>5</Доход>
      <Расход>4</Расход>
      <Разница>1</Разница>
    </Месяц 5>
  </Налог>
</Name1>
 


Это сообщение отредактировал(а) Zloxa - 1.3.2010, 15:54


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
davidoffpk
Дата 1.3.2010, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Zloxa @ 1.3.2010,  15:53)
Мне не настолько сложно написать этот запрос, насколько Вам сложно будет его понять.

Что правда, то правда... Но все же спасибо за потраченное время и силы. Может мне это и поможет)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "XML/XSLT"
diadiavova

Прежде чем опубликовать вопрос, попробуйте воспользоваться поиском - возможно тема уже поднималась.

Также рекомендуем Вам зайти в раздел FAQ ,раздел дополняется и, возможно, там вы увидите готовое решение.

Для ответов на часто задаваемые вопросы существует FAQ раздела. Новости можно публиковать в разделе новостей. Для статей так же есть специальный раздел

Желаем удачи в Вашем деле!


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

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | XML, XSL | Следующая тема »


 




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


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

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