Рекурсивное преобразование Xslt

Я пробовал всеми способами, но я не получил никакого результата. Как я могу преобразовать с помощью XSLT такой XML:

<root>
     <row>topic</row>
     <row>Topic1</row>
     <row>words</row>
     <row>word1</row>
     <row>word2</row>
     <row>word3</row>
     <row>words</row>
     <row>word4</row>
     <row>word5</row>
     <row>word6</row>
     <row>topic</row>
     <row>Topic2</row>
     <row>words</row>
     <row>word7</row>
     <row>word8</row>
     <row>word9</row>
     <row>topic</row>
     <row>Topic3</row>
     <row>words</row>
     <row>word10</row>
     <row>word11</row>
     <row>word12</row>
</root>

В таком XML?

<topic>Topic1
    <words>word1word2word3word4word5word6</words>
</topic>
<topic>Topic2
    <words>word7word8word9</words>
</topic>
<topic>Topic3
    <words>word10word11word12</words>
</topic>

Значение «тема» и «слова» регулярно встречаются в XML, и я бы сначала сгруппировал по теме, а в каждой теме сгруппировал слова по «словам»...

Спасибо заранее!


person AmintaCode    schedule 22.11.2016    source источник
comment
Ваш процессор поддерживает XSLT 2.0?   -  person michael.hor257k    schedule 23.11.2016
comment
Да, он поддерживает XSLT 2.0!   -  person AmintaCode    schedule 23.11.2016


Ответы (1)


В XSLT 2.0 вы могли бы так просто:

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

<xsl:template match="root">
    <xsl:copy>
        <xsl:for-each-group select="row" group-starting-with="row[.='topic']">
            <topic>
                <xsl:value-of select="current-group()[2]"/>
                <words>
                    <xsl:value-of select="current-group()[position() gt 3]" separator=""/>
                </words>
            </topic>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
person michael.hor257k    schedule 22.11.2016
comment
что, если вместо ‹строка›Тема1‹/строка› или ‹строка›Тема2‹/строка› у меня было ‹строка›‹ячейка›a‹/ячейка›‹ячейка›b‹/ячейка›‹ячейка›c‹/ячейка› ‹/строка› и т. д.? Как я могу вывести каждую ячейку в элементе ‹newcell›? @michael.hor257k - person AmintaCode; 23.11.2016
comment
@AmintaCode Я не вижу связи с текущим вопросом. Почему не публикуете новый? - person michael.hor257k; 23.11.2016
comment
Хорошо, спасибо, вы правы! Однако я использовал <xsl:apply-templates select="current-group()[2]/cell" /> для вывода значений.... - person AmintaCode; 23.11.2016
comment
А, теперь понял (думаю). Очень сложно читать код в комментариях, особенно. частичный код. - person michael.hor257k; 23.11.2016
comment
Я думаю, что, возможно, было бы полезно узнать, как получить тот же результат без использования ‹xsl:for-each-group›, возможно ли это? @michael.hor257k - person AmintaCode; 23.11.2016
comment
Это проблема группировки, а в XSLT 2.0 есть инструмент для группировки. Не вижу смысла искать альтернативу. - person michael.hor257k; 23.11.2016
comment
Спасибо! Я вижу, вы очень хорошо разбираетесь в Xslt, интересно, не хотите ли вы взглянуть на другой мой вопрос stackoverflow.com/questions/40794064/. @michael.hor257k - person AmintaCode; 24.11.2016