powered by simpleCommunicator - 2.0.18     © 2024 Programmizd 02
Map
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Файл стиля XSLT
7 сообщений из 7, страница 1 из 1
Файл стиля XSLT
    #40131198
eliasum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Есть входной xml файл:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
<Item key="k1" title="t1" description="d1">
  <Adress title="t2" description="d2">
    <Template key="01,09-10,21" title="d3" description="d3">
      <Channel title="t4" description="d4">
        <Template key="1-3" title="t5" description="d5" />
      </Channel>
    </Template>
  </Adress>
</Item>



Его нужно трансформировать к такому виду:
Код: 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.
<Item key="k1" title="t1" description="d1">
  <Adress title="t2" description="d2">
    <Item key="01" title="d3" description="d3">
      <Channel title="t4" description="d4">
        <Item key="1" title="t5" description="d5" />
        <Item key="2" title="t5" description="d5" />
        <Item key="3" title="t5" description="d5" />
      </Channel>
    </Item>
    <Item key="09" title="d3" description="d3">
      <Channel title="t4" description="d4">
        <Item key="1" title="t5" description="d5" />
        <Item key="2" title="t5" description="d5" />
        <Item key="3" title="t5" description="d5" />
      </Channel>
    </Item>
    <Item key="10" title="d3" description="d3">
      <Channel title="t4" description="d4">
        <Item key="1" title="t5" description="d5" />
        <Item key="2" title="t5" description="d5" />
        <Item key="3" title="t5" description="d5" />
      </Channel>
    </Item>
    <Item key="21" title="d3" description="d3">
      <Channel title="t4" description="d4">
        <Item key="1" title="t5" description="d5" />
        <Item key="2" title="t5" description="d5" />
        <Item key="3" title="t5" description="d5" />
      </Channel>
    </Item>
  </Adress>
</Item>



На данный момент написал такой файл стилей:
Код: 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.
<?xml version="1.0" encoding="utf-8"?>
 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  
    <!--Identity template-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
        
    <xsl:template name="tokenize">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="','"/>
        <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
            <xsl:if test="$token and not(contains($token, '-'))">
                <Item key="{$token}"/>
            </xsl:if>
            
            <!--enumerate-->
            <xsl:if test="contains($token, '-')">
                <xsl:call-template name="enumerate">
                    <xsl:with-param name="start" select="substring($token, 1, 2)"/>
                    <xsl:with-param name="end" select="substring($token, 4, 5)"/>
                </xsl:call-template>
            </xsl:if>
            <xsl:text>
</xsl:text>
            
            <xsl:if test="contains($text, $delimiter)">
                <!-- recursive call -->
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>                
            </xsl:if>
    </xsl:template>
    
    <xsl:template name="enumerate">
        <xsl:param name="start"/>
        <xsl:param name="end"/>
        <xsl:if test="$start">
            <Item key="{$start}"/>
        </xsl:if>
        <xsl:if test="$start &lt; $end">
            <xsl:text>
</xsl:text>
            <xsl:call-template name="enumerate">
                <xsl:with-param name="start" select="format-number($start + 1,'00')"/>
                <xsl:with-param name="end" select="format-number($end,'00')"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    
    <xsl:template match="Template">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="@key"/>
            </xsl:call-template>    
    </xsl:template> 
    
</xsl:stylesheet>



Не получается сделать обход правильно для нужного числа новых тегов Item и соответствующих значений атрибутов key.
P.S. XSLT Version:1.0, XSLT Processor:Microsoft
...
Рейтинг: 0 / 0
Файл стиля XSLT
    #40131219
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как минимум, общий шаблон
eliasum
Код: xml
1.
<xsl:template match="@*|node()">

должен быть самым последним
...
Рейтинг: 0 / 0
Файл стиля XSLT
    #40131232
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если поисправлять остальные ошибки (в частности, неправильное формирование Item) и провести небольшую оптимизацию, то получится вот так
Код: 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.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    
    <xsl:template match="Template">
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="concat(@key, ',')"/>
            <xsl:with-param name="delimiter" select="','"/>
        </xsl:call-template>    
    </xsl:template> 
    
    <!-- Skip process Template/@key -->
    <xsl:template match="Template/@key"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template name="tokenize">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="','"/>
        <xsl:variable name="token" select="substring-before($text, $delimiter)" />
        <xsl:if test="$token != ''">
            <xsl:choose>
                <xsl:when test="contains($token, '-')">
                    <xsl:call-template name="enumerate">
                        <xsl:with-param name="start" select="substring-before($token, '-')"/>
                        <xsl:with-param name="end" select="substring-after($token, '-')"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="enumerate">
                        <xsl:with-param name="start" select="$token"/>
                        <xsl:with-param name="end" select="$token"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="delimiter" select="$delimiter"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    
    <xsl:template name="enumerate">
        <xsl:param name="start"/>
        <xsl:param name="end"/>
        <xsl:if test="$start &lt;= $end">
            <Item key="{number($start)}">
                <!-- Copy attributes -->
                <xsl:apply-templates select="@*"/>
            </Item>
            <xsl:call-template name="enumerate">
                <xsl:with-param name="start" select="$start + 1"/>
                <xsl:with-param name="end" select="$end"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

...
Рейтинг: 0 / 0
Файл стиля XSLT
    #40131238
eliasum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, спасибо за ответ!

Ваш код трансформирует в такой файл xml:
Код: xml
1.
2.
3.
4.
5.
<Item key="k1" title="t1" description="d1">
  <Adress title="t2" description="d2">
	<Item key="1" title="d3" description="d3" /><Item key="9" title="d3" description="d3" /><Item key="10" title="d3" description="d3" /><Item key="21" title="d3" description="d3" />
  </Adress>
</Item>



https://www.xsltfiddle.liberty-development.net/pNP54dX
...
Рейтинг: 0 / 0
Файл стиля XSLT
    #40131242
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eliasum
Ваш код трансформирует в такой файл xml:
Опять 25. XML - это НЕ ТЕКСТОВЫЙ формат. И просматривать его в блокноте нельзя. Откройте любой браузер и смотрите там
...
Рейтинг: 0 / 0
Файл стиля XSLT
    #40131245
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А для обработки Channel нужно изменить

_Vasilisk_
Код: xml
1.
2.
3.
4.
<Item key="{number($start)}">
  <!-- Copy attributes -->
  <xsl:apply-templates select="@*"/>
</Item>

на
Код: xml
1.
2.
3.
4.
5.
6.
<Item key="{number($start)}">
  <!-- Copy attributes -->
  <xsl:apply-templates select="@*"/>
  <!-- Process childs -->
  <xsl:apply-templates/>
</Item>
...
Рейтинг: 0 / 0
Файл стиля XSLT
    #40131249
eliasum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, спасибо большое, всё работает!
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Файл стиля XSLT
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (1): Анонимы (1)
Читали форум (1): Анонимы (1)
Пользователи онлайн (6): Анонимы (4), Bing Bot, Yandex Bot 3 мин.
x
x
Закрыть


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