На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ANDLL
  
> создание структуры xml-документа из атрибута в виде пути
    Всем добрый день!
    XSLT только-только начал изучать и вот наткнулся на проблему.

    Есть XML-документ следующего вида:
    Скрытый текст
    ExpandedWrap disabled
      <?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 Парфюмерная вода мужская "De La Mer " 75 мл"
                  ОписаниеНоменклатуры="«De La Mer» Легкий и молодежный." Цена="255"
                  РекомендуемаяРозничнаяЦена="450" РазделКаталогаТоваров="мужские"
                  СписокРазделовКаталогаТоваров="Косметика:Феромоны:мужские">
                  <Описание><![CDATA[«De La Mer» Легкий и молодежный.]]></Описание>
              </Номенклатура>
              <Номенклатура id="4834"
                  Наименование="Natural Instinct Парфюмерная вода мужская "Triomphateur" 75 мл."
                  ОписаниеНоменклатуры="«Triomphateur» Динамичный и полный энергии."
                  Цена="255" РекомендуемаяРозничнаяЦена="450" РазделКаталогаТоваров="мужские"
                  СписокРазделовКаталогаТоваров="Косметика:Феромоны:мужские">
                  <Описание><![CDATA[«Triomphateur» Динамичный и полный энергии.]]></Описание>
              </Номенклатура>
              <Номенклатура id="4961"
                  Наименование="Мусс для интимной гигиены (L'n'H) 150мл."
                  ОписаниеНоменклатуры="Это воздушное и деликатное средство для ежедневной гигиены."
                  Цена="358" РекомендуемаяРозничнаяЦена="895"
                  СписокРазделовКаталогаТоваров="Косметика:Интимная гигиена"
                  РазделКаталогаТоваров="Интимная гигиена">
                  <Описание><![CDATA[Это воздушное и деликатное средство для ежедневной.]]></Описание>
              </Номенклатура>
              <Номенклатура id="4962"
                  Наименование="Эмульсия для интимной гигиены (L'n'H) 200мл."
                  ОписаниеНоменклатуры='"Это прекрасное  экономичное средство для ежедневного бережного ухода."'
                  Цена="346" РекомендуемаяРозничнаяЦена="865" РазделКаталогаТоваров="Интимная гигиена"
                  СписокРазделовКаталогаТоваров="Косметика:Интимная гигиена">
                  <Описание><![CDATA["Это прекрасное  экономичное средство для ежедневного бережного ухода.]]></Описание>
              </Номенклатура>
          </Раздел>
      </КаталогТоваров>


    Элементов <Раздел> может быть несколько, но они не могут быть вложенными друг в друга. Истинная же структура каталога хранится в атрибуте @СписокРазделовКаталогаТоваров. На выходе нужен документ следующего вида
    Скрытый текст
    ExpandedWrap disabled
      <?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, но не в этом соль:
    Скрытый текст
    ExpandedWrap disabled
      <?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>


    Проблема, как мне кажется вот с этой строкой:
    Скрытый текст
    ExpandedWrap disabled
          <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> в данном случае, то это будет ещё лучше. :)
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0268 ]   [ 16 queries used ]   [ Generated: 19.04.24, 15:03 GMT ]