Гость
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Фильтрация и последующая сортировка / 16 сообщений из 16, страница 1 из 1
10.03.2006, 14:28
    #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
10.03.2006, 18:06
    #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
15.03.2006, 19:05
    #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
Период между сообщениями больше года.
27.11.2010, 20:04
    #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
28.11.2010, 02:21
    #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
28.11.2010, 03:16
    #36981375
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация и последующая сортировка
Решение есть, но не оптимальное. Хотя если используете парсер от Microsoft то можно подшаманить
...
Рейтинг: 0 / 0
28.11.2010, 14:04
    #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
29.11.2010, 19:12
    #36984474
toologic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация и последующая сортировка
не совсем корректно сформировал постановку задачи..

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

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

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

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

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

Хотя не думал, что вопрос формирование Выборки и дальнейшей группировки отобранного займет 5 дней..
...
Рейтинг: 0 / 0
30.11.2010, 12:41
    #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
30.11.2010, 13:10
    #36985834
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация и последующая сортировка
toologic,

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

Ставь сортировку при вызове шаблона
...
Рейтинг: 0 / 0
30.11.2010, 23:42
    #36987518
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация и последующая сортировка
Накаркали Вы. Сегодня сам занимался подобной фигней, да еще и с выводом в непрямоугольную таблицу (это где colspan и rowspan != 1). Вы знаете какой это кайф создавать на XSLT непрямоугольные таблицы? Часа три бился, потом плюнул на все и вспомнил свое золотое правило - чего нельзя сделать за одно преобразование можно за два. Сформировал промежуточное дерево с нужной мне группировкой, а потом уже его вывел в таблицу
...
Рейтинг: 0 / 0
01.12.2010, 01:27
    #36987618
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация и последующая сортировка
_Vasilisk_Накаркали Вы. Сегодня сам занимался подобной фигней, да еще и с выводом в непрямоугольную таблицу (это где colspan и rowspan != 1). Вы знаете какой это кайф создавать на XSLT непрямоугольные таблицы? Часа три бился, потом плюнул на все и вспомнил свое золотое правило - чего нельзя сделать за одно преобразование можно за два. Сформировал промежуточное дерево с нужной мне группировкой, а потом уже его вывел в таблицуЗаитнтриговал. выкладывай задачку, не решу, хоть развлекусь. ИМХО любое преобразование можно сделать в один проход.
...
Рейтинг: 0 / 0
01.12.2010, 22:51
    #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
01.12.2010, 22:53
    #36990164
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Фильтрация и последующая сортировка
Ну и дополнительное условие - XML большой, поэтому все выборки должны быть максимально оптимизированы
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Фильтрация и последующая сортировка / 16 сообщений из 16, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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