powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Фильтрация и последующая сортировка
16 сообщений из 16, страница 1 из 1
Фильтрация и последующая сортировка
    #33592832
ДмитрийЦ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть xml:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<records>
	<contact>
		<title>A</title>
		<surname>Sur2</surname>
	</contact>
        <contact>
		<title>C</title>
		<surname>Sur2</surname>
	</contact>
	<contact>
		<title>A</title>
		<surname>Sur1</surname>
	</contact>
	<contact>
		<title>A</title>
		<surname>Sur3</surname>
	</contact>
	<contact>
		<title>E</title>
		<surname>Sur3</surname>
	</contact>
</records>

Нужно вывести мкасимальный <title> для каждой <surname> (т.е. для xml выше должны получиться:
<surname>Sur2</surname> - <title>C</title>, <surname>Sur1</surname> - <title>A</title>, <surname>Sur3</surname> - <title>E</title> )

У меня получилось только вот что:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
<xsl:key name="contacts-by-surname" match="contact" use="surname"/>
<xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[1]) = 1]">
<xsl:sort select="title" data-type="text" order="descending"/>
	<xsl:value-of select="surname"/>
	<xsl:for-each select="key('contacts-by-surname',surname)">
			<xsl:sort select="title" order="descending" data-type="text"/>
			<xsl:if test="position()=1">Max:<xsl:value-of select="title"/></xsl:if>
	</xsl:for-each>
</xsl:for-each>

Но тут не получается сортировка, т.к. сортирует он, видимо, по первым записям в ключе. Наверное, решение какое-то тривиальное, и умещается в пару строк, но я "застрял". Помогите, пожалуйста, разобраться
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #33593671
Фотография B0rG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Интересный подход. Обидно только что неправильный...

Я бы сделал так...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<xsl:template match="records">
	<xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[1]) = 1]">
		<xsl:variable name="s" select="surname/text()" />
		<xsl:apply-templates select="//contact[surname/text() = $s]" mode="first">
			<xsl:sort select="title" data-type="text" order="descending" />
		</xsl:apply-templates>
		<br />
	</xsl:for-each>
</xsl:template>

<xsl:template match="contact" mode="first">
	<xsl:if test="position() = 1">
		<xsl:value-of select="surname/text()" /> : 
		<xsl:value-of select="title/text()" />
	</xsl:if>
</xsl:template>

Cheers
Pete
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #33603481
ДмитрийЦ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения, я неточно сформулировал задачу. Точнее, в заголовке я ее сформулировал, а в теле сообщения в явной форме - нет.
Нужно не только отобрать максимальные <title> для каждой <surname>, но и при выводе выводить записи, сортируя из по этому самому максимальному <title>.
Т.е. в примере из первого сообщения на выходе должно быть:

<surname>Sur1</surname> - <title>A </title>
<surname>Sur2</surname> - <title> C </title>
<surname>Sur3</surname> - <title> E </title>

Отбор максимальных версий в моем варианте проходит, а вот сортировка - нет.
В Вашем варианте сортировка тоже не производится - записи выводятся в порядке из первого появления в xml-файле.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Фильтрация и последующая сортировка
    #36980951
toologic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Аналогичная задача..

есть поток xml


Код: plaintext
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.
<root>
  <item>
     <key> 1 </key>
     <param>a</param>
     <flag> 12 </flag>
     <text>This is text</text>
  </item>
  <item>
     <key> 3 </key>
     <param>b</param>
     <flag> 13 </flag>
     <text>This is text</text>
  </item>
.....
  <item>
     <key> 1 </key>
     <param>a</param>
     <flag> 13 </flag>[CODE=xml]

     <text>This is text</text>
  </item>
  .....
  <item>
     <key> 2 </key>
     <param>b</param>
     <flag> 12 </flag>
     <text>This is text</text>
  </item>
</root>

Задача
1. Отфильтровать поток по признаку key = 1 и param=a
2. Оставшиеся данные сгруппировать по признаку flag. Т.е. Берем первое значение flag - и выводим все записи с таким значением, второе и так. далее..

входной XML - большой - порядка 400-700 записей item/ посему оптимизация алгоритма важна...

Реализация которая у меня есть выполняет только 2 задачу


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="utf-8" />

  <xsl:key name="contacts-by-surname" match="item" use="flag" />

<xsl:template match="root">
  <xsl:for-each select="item[count(. | key('contacts-by-surname', flag)[1]) = 1]">

... обработка данных
</xsl:for-each>

</xsl:template>
Попытки вставить куда нить xsl:if test="key=1" результатов не дают.

PS к сожалению, ограничен только Transform

Буду искренне признателен подсказке по решению...
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36981351
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
toologic,

не вкуриваю, что значит отфильтровать?
так не катит?
Код: plaintext
1.
2.
3.
<xs:for-each select="item[ key/text() = '1' and param/text() = 'á' ]">
    <xsl:sort select="flag" type="number" />
    ...
</xsl:for-each>
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36981375
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решение есть, но не оптимальное. Хотя если используете парсер от Microsoft то можно подшаманить
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36981625
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Придумал
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="utf-8" />

  <xsl:template match="/root">
    <xsl:variable name="nodes" select="item[key = 1 and param = 'a']"/>
    <xsl:apply-templates select="$nodes" mode="flag">
      <xsl:with-param name="nodes" select="$nodes"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="item" mode="flag">
    <xsl:param  name="nodes"/>
    <xsl:if test="generate-id(.) = generate-id($nodes[flag = current()/flag])">
      <xsl:apply-templates select="$nodes[flag = current()/flag]" mode="data"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="item" mode="data">
    ..............
    Выводим данные
    ..............
  </xsl:template>
</xsl:stylesheet>
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36984474
toologic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не совсем корректно сформировал постановку задачи..

Назвать ее нужно так. Фильтрация и последующая группировка.
в общих чертах - есть поток xml (например одежда: пальто, куртки, плащи, брюки и т.д.)
Мне нужно
1. Отобрать вначале только 1)куртки 2) из нейлона
2. Отобранные данные сгруппировать по производителю, вывести название моделей.

Мне видится это так (учитывайте, то я в xml+xsl ни бумбум, но из прочтенного и протестированного в vs 2008)
сформировать темплейт, который отбирает только key=1 and param=b
на эту выборку напустить темплейт, который сгруппирует данные.
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36984489
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
toologicне совсем корректно сформировал постановку задачи..
Назвать ее нужно так. Фильтрация и последующая группировка......
Ты не мудри - ты пальцем покажи...

Сделай типовой xml c исходным деревом и какой должен получится xml c конечным (или результирующий html, text).
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36984521
toologic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Браво! Ваш код отработал на 100%

я чувствовал что решение простое и элегантное..

Хотя не думал, что вопрос формирование Выборки и дальнейшей группировки отобранного займет 5 дней..
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36985727
toologic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Подскажите, в коде:
Код: plaintext
1.
2.
3.
4.
5.
  <xsl:template match="item" mode="data">
    ..............
    Выводим данные
    ..............
  </xsl:template>
</xsl:stylesheet>

можно вставлять сортировку по любому тегу внутри item? Т.е. допустимо ли?
Код: plaintext
1.
  <xsl:template match="item" mode="data">
<xsl:sort select="flag" order="ascending"/>
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36985834
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
toologic,

xsl:sort может содержаться в элементах xsl:apply-templates или xsl:for-each ( Sorting )

Ставь сортировку при вызове шаблона
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36987518
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Накаркали Вы. Сегодня сам занимался подобной фигней, да еще и с выводом в непрямоугольную таблицу (это где colspan и rowspan != 1). Вы знаете какой это кайф создавать на XSLT непрямоугольные таблицы? Часа три бился, потом плюнул на все и вспомнил свое золотое правило - чего нельзя сделать за одно преобразование можно за два. Сформировал промежуточное дерево с нужной мне группировкой, а потом уже его вывел в таблицу
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36987618
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Накаркали Вы. Сегодня сам занимался подобной фигней, да еще и с выводом в непрямоугольную таблицу (это где colspan и rowspan != 1). Вы знаете какой это кайф создавать на XSLT непрямоугольные таблицы? Часа три бился, потом плюнул на все и вспомнил свое золотое правило - чего нельзя сделать за одно преобразование можно за два. Сформировал промежуточное дерево с нужной мне группировкой, а потом уже его вывел в таблицуЗаитнтриговал. выкладывай задачку, не решу, хоть развлекусь. ИМХО любое преобразование можно сделать в один проход.
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36990162
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давай. Есть XML такой структуры
Код: plaintext
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.
<Root>
  <Table1>
    <Row>
      <ID> 1 </ID>
      <NAME>Name1</NAME>
    </Row>
    <Row>
      <ID> 2 </ID>
      <NAME>Name2</NAME>
    </Row>
    ...............
    <Row>
      <ID>n</ID>
      <NAME>Namen</NAME>
    </Row>
  </Table1>
  <Table2>
    <Row>
      <ID> 1 </ID>
      <TABLE1_ID> 1 </TABLE1_ID>
      <PERIOD> 1 </PERIOD>
      <GROUP> 1 </GROUP>
    </Row>
    <Row>
    ...............
    <Row>
      <ID>n1</ID>
      <TABLE1_ID>n2</TABLE1_ID>
      <PERIOD>n3</PERIOD>
      <GROUP>n4</GROUP>
    </Row>
  </Table2>
  <Table3>
    <Row>
      <ID> 1 </ID>
      <TABLE2_ID> 1 </TABLE2_ID>
      <MONTH> 1 </MONTH>
      <DATA>Data1</DATA>
    </Row>
    <Row>
    ...............
    <Row>
      <ID>m1</ID>
      <TABLE2_ID>m2</TABLE2_ID>
      <MONTH>m3</MONTH>
      <DATA>Datam4</DATA>
    </Row>
  </Table3>
</Root>
Краткие пояснения
ID в каждой таблице это уникальный идентификатор в данной таблице. Может идти в любом порядке.

В Table2 теги TABLE1_ID, PERIOD, GROUP никак не коррелируют между собой. TABLE1_ID ссылается на запись в первой таблице, PERIOD, GROUP - перечислимые типы.

В Table3 TABLE2_ID ссылка на запись из второй таблице, MONTH - может принимать значение от 1 до 12. На одну запись из второй таблицы может ссылаться не более 12 записей из третьей таблицы. Причем на одну запись из второй таблицы может ссылаться не более одной записи из третьей таблицы с конкретным месяцем.

Теперь задача - сформировать HTML таблицу с полями
Table1/NAME Table2/PERIOD Table2/GROUP Table3/Row[MONTH = 1]/DATA ... Table3/Row[MONTH = 1]/DATA
последовательно сгруппированную (т.е. ячейки должны быть с соответствующим colspan) по полям NAME, PERIOD, GROUP
...
Рейтинг: 0 / 0
Фильтрация и последующая сортировка
    #36990164
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и дополнительное условие - XML большой, поэтому все выборки должны быть максимально оптимизированы
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Фильтрация и последующая сортировка
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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