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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> создание структуры xml-документа из атрибута в вид, преобразование XML в XML 
:(
    Опции темы
villainus
  Дата 25.5.2014, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем добрый день!
XSLT только-только начал изучать и вот наткнулся на проблему.

Есть XML-документ следующего вида:
Код

<?xml version="1.0" encoding="UTF-8"?>
<КаталогТоваров Дата="05.05.2014">
    <Раздел Наименование="Косметика и Парфюмерия">
        <Номенклатура id="4679"
            Наименование="Natural Instinct Освежающий тоник для тела Мандарин 95 мл"
            ОписаниеНоменклатуры="Необыкновенный, свежий, искрящийся цитрусовый аромат."
            Цена="165" РекомендуемаяРозничнаяЦена="250" РазделКаталогаТоваров="женские"
            СписокРазделовКаталогаТоваров="Косметика:Феромоны:женские">
            <Описание><![CDATA[Необыкновенный, свежий, искрящийся цитрусовый аромат.]]></Описание>
        </Номенклатура>
        <Номенклатура id="4680"
            Наименование="Natural Instinct Освежающий тоник для тела Малина 95 мл"
            ОписаниеНоменклатуры="Нежный, сладкий и благоухающим ароматом, пробуждает инстинкты и чувственность."
            Цена="165" РекомендуемаяРозничнаяЦена="250" РазделКаталогаТоваров="женские"
            СписокРазделовКаталогаТоваров="Косметика:Феромоны:женские">
            <Описание><![CDATA[Нежный, сладкий и благоухающим ароматом, пробуждает инстинкты и чувственность.]]></Описание>
        </Номенклатура>
        <Номенклатура id="4833"
            Наименование="Natural Instinct Парфюмерная вода мужская &quot;De La Mer &quot; 75 мл"
            ОписаниеНоменклатуры="«De La Mer» Легкий и молодежный." Цена="255"
            РекомендуемаяРозничнаяЦена="450" РазделКаталогаТоваров="мужские"
            СписокРазделовКаталогаТоваров="Косметика:Феромоны:мужские">
            <Описание><![CDATA[«De La Mer» Легкий и молодежный.]]></Описание>
        </Номенклатура>
        <Номенклатура id="4834"
            Наименование="Natural Instinct Парфюмерная вода мужская &quot;Triomphateur&quot; 75 мл."
            ОписаниеНоменклатуры="«Triomphateur» Динамичный и полный энергии."
            Цена="255" РекомендуемаяРозничнаяЦена="450" РазделКаталогаТоваров="мужские"
            СписокРазделовКаталогаТоваров="Косметика:Феромоны:мужские">
            <Описание><![CDATA[«Triomphateur» Динамичный и полный энергии.]]></Описание>
        </Номенклатура>
        <Номенклатура id="4961"
            Наименование="Мусс для интимной гигиены (L'n'H) 150мл."
            ОписаниеНоменклатуры="Это воздушное и деликатное средство для ежедневной гигиены."
            Цена="358" РекомендуемаяРозничнаяЦена="895"
            СписокРазделовКаталогаТоваров="Косметика:Интимная гигиена"
            РазделКаталогаТоваров="Интимная гигиена">
            <Описание><![CDATA[Это воздушное и деликатное средство для ежедневной.]]></Описание>
        </Номенклатура>
        <Номенклатура id="4962"
            Наименование="Эмульсия для интимной гигиены (L'n'H) 200мл."
            ОписаниеНоменклатуры='"Это прекрасное  экономичное средство для ежедневного бережного ухода."'
            Цена="346" РекомендуемаяРозничнаяЦена="865" РазделКаталогаТоваров="Интимная гигиена"
            СписокРазделовКаталогаТоваров="Косметика:Интимная гигиена">
            <Описание><![CDATA["Это прекрасное  экономичное средство для ежедневного бережного ухода.]]></Описание>
        </Номенклатура>
    </Раздел>
</КаталогТоваров>


Элементов <Раздел> может быть несколько, но они не могут быть вложенными друг в друга. Истинная же структура каталога хранится в атрибуте @СписокРазделовКаталогаТоваров. На выходе нужен документ следующего вида:
Код

<?xml version="1.0" encoding="UTF-8"?>
<eshop id="10022484">
    <cat>
        <title>Косметика</title>
        <descr></descr>
        <link>http://example2.ru/store/012/</link>
        <cat>
            <title>Феромоны</title>
            <descr></descr>
            <link>http://example2.ru/store/034/</link>
            <cat>
                <title>женские</title>
                <descr></descr>
                <link>http://example2.ru/store/05/</link>
                <positions>
                    <pos>
                        <uid>4679</uid>
                        <title>Natural Instinct Освежающий тоник для тела Мандарин 95 мл
                        </title>
                        <price>250</price>
                        <price1>0</price1>
                        <price2>0</price2>
                        <currency>1</currency>
                        <amount_left>0</amount_left>
                        <producer></producer>
                        <descr>Необыкновенный, свежий, искрящийся цитрусовый аромат.
                        </descr>
                        <link>http://example2.ru/store/012345/?pos=4679</link>
                    </pos>
                    <pos>
                        <uid>4680</uid>
                        <title>Natural Instinct Освежающий тоник для тела Малина 95 мл
                        </title>
                        <price>250</price>
                        <price1>0</price1>
                        <price2>0</price2>
                        <currency>1</currency>
                        <amount_left>0</amount_left>
                        <producer></producer>
                        <descr>Нежный, сладкий и благоухающим ароматом, пробуждает
                            инстинкты и чувственность.</descr>
                        <link>http://example2.ru/store/012345/?pos=4680</link>
                    </pos>
                </positions>
            </cat>
            <cat>
                <title>мужские</title>
                <descr></descr>
                <link>http://example2.ru/store/05/</link>
                <positions>
                    <pos>
                        <uid>4833</uid>
                        <title>Natural Instinct Парфюмерная вода мужская "De La Mer
                            " 75 мл</title>
                        <price>450</price>
                        <price1>0</price1>
                        <price2>0</price2>
                        <currency>1</currency>
                        <amount_left>0</amount_left>
                        <producer></producer>
                        <descr>«De La Mer» Легкий и молодежный.</descr>
                        <link>http://example2.ru/store/012345/?pos=4833</link>
                    </pos>
                    <pos>
                        <uid>4834</uid>
                        <title>Natural Instinct Парфюмерная вода мужская
                            "Triomphateur" 75 мл.</title>
                        <price>450</price>
                        <price1>0</price1>
                        <price2>0</price2>
                        <currency>1</currency>
                        <amount_left>0</amount_left>
                        <producer></producer>
                        <descr>«Triomphateur» Динамичный и полный энергии.</descr>
                        <link>http://example2.ru/store/012345/?pos=4834</link>
                    </pos>
                </positions>
            </cat>
        </cat>
        <cat>
            <title>Интимная гигиена</title>
            <descr></descr>
            <link>http://example2.ru/store/78/</link>
            <positions>
                <pos>
                    <uid>4961</uid>
                    <title>Мусс для интимной гигиены (L'n'H) 150мл.</title>
                    <price>895</price>
                    <price1>0</price1>
                    <price2>0</price2>
                    <currency>1</currency>
                    <amount_left>0</amount_left>
                    <producer></producer>
                    <descr>Это воздушное и деликатное средство для ежедневной гигиены.
                    </descr>
                    <link>http://example2.ru/store/012345/?pos=4961</link>
                </pos>
                <pos>
                    <uid>4962</uid>
                    <title>Эмульсия для интимной гигиены (L'n'H) 200мл.</title>
                    <price>865</price>
                    <price1>0</price1>
                    <price2>0</price2>
                    <currency>1</currency>
                    <amount_left>0</amount_left>
                    <producer></producer>
                    <descr>"Это прекрасное экономичное средство для ежедневного
                        бережного ухода."</descr>
                    <link>http://example2.ru/store/012345/?pos=4962</link>
                </pos>
            </positions>
        </cat>
    </cat>
</eshop>


Вот xsl-файл преобразования. он пока не формирует корневой тэг e-shop, но не в этом соль: 
Код

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:key name="ixNom" match="/КаталогТоваров/Раздел/Номенклатура"
use="@СписокРазделовКаталогаТоваров" />
  <xsl:key name="NomByPart" match="/КаталогТоваров/Раздел/Номенклатура"
use="substring-before(@СписокРазделовКаталогаТоваров,':')" />
  <xsl:variable name="Part" select="/КаталогТоваров/Раздел/Номенклатура
[generate-id(.) = generate-id(key('NomByPart', substring-before(./@СписокРазделовКаталогаТоваров,':')))]" />
  <xsl:variable name="catParagraph" select="/КаталогТоваров/Раздел/Номенклатура
[generate-id(.) = generate-id(key('ixNom', ./@СписокРазделовКаталогаТоваров))]" />
  
  <xsl:template match="/">
    <html>
    <body>
    <xsl:for-each select="$Part">
      <xsl:sort select="@СписокРазделовКаталогаТоваров" />
      <xsl:call-template name="Partitions">
        <xsl:with-param name="section" select="./@СписокРазделовКаталогаТоваров" />
      </xsl:call-template>
    </xsl:for-each>
    <xsl:value-of select="count($catParagraph)" />
    </body>
    </html>
  </xsl:template>
  
  <xsl:template match="Номенклатура">

  </xsl:template>
  <xsl:template name="Partitions">
    <xsl:param name="section" />
    <xsl:param name="delimeter" select="':'" />
    <xsl:param name="currentSection" select="substring-before($section,$delimeter)" />
    <xsl:variable name="csL" select="string-length($currentSection)" />
    <!-- Чушь. Нужно сделать выборку уникальных подразделов в данном разделе -->
    <xsl:variable name="sectionList" select="/КаталогТоваров/Раздел/Номенклатура
     [generate-id(.) = generate-id(/КаталогТоваров/Раздел/Номенклатура
     [starts-with(@СписокРазделовКаталогаТоваров, concat($currentSection, $delimeter,
     substring-before(substring(@СписокРазделовКаталогаТоваров, $csL+2), $delimeter)))])] " />
    <xsl:for-each select="$sectionList">
      <xsl:variable name="stSection" select="concat($currentSection, $delimeter, 
substring-before(substring(@СписокРазделовКаталогаТоваров,$csL+2), $delimeter))" />
      <xsl:variable name="endSection" select="substring(@СписокРазделовКаталогаТоваров,$csL+2)" />
      <xsl:choose>
        <xsl:when test="contains($endSection, $delimeter)">
          <xsl:element name="cat">
            <xsl:element name="title"><xsl:value-of select="substring-before($endSection, $delimeter)" /></xsl:element>
            <descr />
            <link>http://sexychel.ru/store/10074723/</link>
            <xsl:call-template name="Partitions">
             <xsl:with-param name="section" select="substring-after($endSection, $delimeter)" />
             <xsl:with-param name="currentSection" select="$stSection" />
            </xsl:call-template>
          </xsl:element>
       </xsl:when>
       <xsl:otherwise>
          <xsl:element name="cat">
            <xsl:element name="title"><xsl:value-of select="$endSection" /></xsl:element>
            <descr />
            <link>http://sexychel.ru/store/10074723/</link>
            <xsl:element name="positions">
              <xsl:for-each select="/КаталогТоваров/Раздел/Номенклатура
              [@СписокРазделовКаталогаТоваров=concat($stSection, $endSection)]">
                <xsl:element name="pos">
                  <uid><xsl:value-of select="@id"/></uid>
                  <title><xsl:value-of select="@Наименование"/></title>
                  <price><xsl:value-of select="@РекомендуемаяРозничнаяЦена"/></price>
                  <price1>0</price1>
                  <price2>0</price2>
                  <currency>1</currency>
                  <amount_left>0</amount_left>
                  <producer/>
                  <descr><xsl:value-of select="./Описание"/></descr>
                  <link>http://sexychel.ru/store/10074723/?pos=<xsl:value-of select="@id"/></link>
                </xsl:element>
              </xsl:for-each>
            </xsl:element>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each> 
  </xsl:template>

</xsl:stylesheet>



Проблема, как мне кажется вот с этой строкой: 
Код

    <xsl:variable name="sectionList" select="/КаталогТоваров/Раздел/Номенклатура
     [generate-id(.) = generate-id(/КаталогТоваров/Раздел/Номенклатура
     [starts-with(@СписокРазделовКаталогаТоваров, concat($currentSection, $delimeter,
     substring-before(substring(@СписокРазделовКаталогаТоваров, $csL+2), $delimeter)))])] " />


В общем тут нужно, без <xsl:key>, т.к. он не позволяет делать выборку по частичному значению атрибута, выбрать все узлы "Номенклатура" у которых совпадает текущий раздел и разные подразделы на один уровень вниз, без повторений. т.е. группировка.
Уже неделю бьюсь, но результата нет. Кажется, проблема в том, что атрибут @СписокРазделовКаталогаТоваров здесь относится к первому контексту /КаталогТоваров/Раздел/Номенклатура, а нужно взять второй, тот что внутри generate-id.
Хотя, если существует способ использоват <xsl:key> в данном случае, то это будет ещё лучше smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "XML/XSLT"
diadiavova

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

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

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

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


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

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


 




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


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

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