Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Группировка xslt  (Прочитано 4441 раз)
0 Пользователей и 1 Гость смотрят эту тему.
KBAC
Постоялец

ru
Offline Offline
Пол: Мужской

« : 29-01-2014 04:21 » 

Все здравствуйте!

Помогите найти косяк, пожалуйста!

Код: (XML)
<Devices>
                <Device>
                        <Name>АБ1</Name>
                        <Osn></Osn>
                </Device>
                <Device>
                        <Name>ЩАБ2</Name>
                        <Osn>АБ1</Osn>
                </Device>
                <Device>
                        <Name>ЩАБ1</Name>
                        <Osn>АБ1</Osn>
                </Device>
                <Device>
                        <Name>АБ2</Name>
                        <Osn></Osn>
                </Device>
                <Device>
                        <Name>ЩАБ3</Name>
                        <Osn>АБ2</Osn>
                </Device>              
                <Device>
                        <Name>ЩАБ4</Name>
                        <Osn>АБ2</Osn>
                </Device>

</Devices>

И xslt к нему
Код: (XML)
<xsl:key name="src" match="Device" use="Osn"/>

<xsl:template match="Devices">
<xsl:variable name="Name" select="Device/Name"/>
<xsl:apply-templates select="Device[generate-id(.) = generate-id(key('src', $Name))]"/>
</xsl:template>

<xsl:template match="Device">
<devices>
<xsl:variable name="Src" select="Osn"/>
    <xsl:apply-templates select="key('src', $Src)" mode="second"/>
</devices>
</xsl:template>

<xsl:template match="Device" mode="second">
<xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

По задумке на выходе должны получиться два элемента devices внутри сгруппированными по элементам Osn. Но по факту обрабатывается только первый элемент. Не понимаю как должны все элементы быть обработаны.
P.S. Делаю по мануалу http://flack.ru/2010/11/19/yet-another-xsl-group/

Выхлоп:
Код: (XML)
<devices><Device>
                        <Name>ЩАБ2</Name>
                        <Osn>АБ1</Osn>
                </Device><Device>
                        <Name>ЩАБ1</Name>
                        <Osn>АБ1</Osn>
                </Device></devices>
« Последнее редактирование: 29-01-2014 04:35 от KBAC » Записан

У тебя все получится, главное -- верить и делать.
Порадоваться, когда все плохо -- легче, чем ты думаешь.
В действии счастье.
Вовлекая людей важно быть увлеченным чужой жизнью.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 29-01-2014 10:31 » 

Я не очень понимаю, причём тут ключи (в смысле xsl:key). Но группировку можно делать рекурсией, последовательно выбирая группу с одинаковым ключом (ключевым значением), затем все с ключами, больше текущего, и к последней применяя общее правило.

Например:
Код: (XML)
<?xml version="1.0" encoding="utf-8"?>
<Items>
        <Item>
                <Attribute1>D</Attribute1>
                <Attribute2>2</Attribute2>
        </Item>
        <Item>
                <Attribute1>B</Attribute1>
                <Attribute2>1</Attribute2>
        </Item>
        <Item>
                <Attribute1>A</Attribute1>
                <Attribute2>1</Attribute2>
        </Item>
        <Item>
                <Attribute1>C</Attribute1>
                <Attribute2>2</Attribute2>
        </Item>
</Items>

Код: (XML)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="xml" indent="yes"/>

        <xsl:template match="/Items">
                <Groups>
                        <xsl:apply-templates select="./Item" mode="first">
                                <xsl:sort select="./Attribute2"/>
                        </xsl:apply-templates>
                </Groups>
        </xsl:template>

        <xsl:template match="Item" mode="first">
                <xsl:if test="position()=1">
                        <xsl:variable name="key" select="Attribute2"/>
                        <Group>
                                <xsl:copy-of select="$key"/>
                                <xsl:apply-templates select="../Item[Attribute2 = $key]" mode="all"/>
                        </Group>                       
                        <xsl:apply-templates select="../Item[Attribute2 &gt; $key]" mode="first"/>
                </xsl:if>
        </xsl:template>

        <xsl:template match="Item" mode="all">
                <Item>
                        <xsl:copy-of select="Attribute1"/>
                </Item>
        </xsl:template>

</xsl:stylesheet>
Сортировка тут нужна чисто для выбора самого младшего по значению ключа.

Результат:
Код: (XML)
<?xml version="1.0"?>
<Groups>
  <Group>
    <Attribute2>1</Attribute2>
    <Item>
      <Attribute1>B</Attribute1>
    </Item>
    <Item>
      <Attribute1>A</Attribute1>
    </Item>
  </Group>
  <Group>
    <Attribute2>2</Attribute2>
    <Item>
      <Attribute1>D</Attribute1>
    </Item>
    <Item>
      <Attribute1>C</Attribute1>
    </Item>
  </Group>
</Groups>
« Последнее редактирование: 29-01-2014 10:33 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines