Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.217.220.114] |
|
Сообщ.
#1
,
|
|
|
Всем добрый день!
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 Парфюмерная вода мужская "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["Это прекрасное экономичное средство для ежедневного бережного ухода.]]></Описание> </Номенклатура> </Раздел> </КаталогТоваров> Элементов <Раздел> может быть несколько, но они не могут быть вложенными друг в друга. Истинная же структура каталога хранится в атрибуте @СписокРазделовКаталогаТоваров. На выходе нужен документ следующего вида Скрытый текст <?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> в данном случае, то это будет ещё лучше. |