powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / создание структуры xml-документа из атрибута в виде пути
2 сообщений из 2, страница 1 из 1
создание структуры xml-документа из атрибута в виде пути
    #38651396
Villainus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем добрый день!
XSLT только-только начал изучать и вот наткнулся на проблему.

Есть XML-документ следующего вида
Код: xml
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.
<?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
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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
<?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
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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
<?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>



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


В общем тут нужно, без <xsl:key>, т.к. он не позволяет делать выборку по частичному значению атрибута, выбрать все узлы "Номенклатура" у которых совпадает текущий раздел и разные подразделы на один уровень вниз, без повторений. т.е. группировка.
Уже неделю бьюсь, но результата нет. Кажется, проблема в том, что атрибут @СписокРазделовКаталогаТоваров здесь относится к первому контексту /КаталогТоваров/Раздел/Номенклатура, а нужно взять второй, тот что внутри generate-id
...
Рейтинг: 0 / 0
создание структуры xml-документа из атрибута в виде пути
    #38651408
Villainus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообще, если существует способ использоват <xsl:key> в данном случае, то это будет ещё лучше :)
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / создание структуры xml-документа из атрибута в виде пути
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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