Создание XSLT для групповых данных

#xml #xslt

#xml #xslt

Вопрос:

У меня есть XML-данные, подобные этому:

 <data ItemCount="5">
<zrow GroupName="Manager"User="User1" />
<zrow GroupName="Developer"User="User2" />
<zrow GroupName="Manager"User="User3" />
<zrow GroupName="CEO"User="User4" />
<zrow GroupName="CEO"User="User5" />
</data>
  

Я хочу выводить вот так:

 Manager

User1

User3

Developer

User2

CEO

User4

User5
  

Каким должен быть мой XSLT? Я хочу создать XSLT, который должен преобразовать мои данные в указанный выше формат. Не могли бы вы, пожалуйста, помочь мне создать его?

Ответ №1:

Решение на XSLT 2.0:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="data">
        <xsl:for-each-group select="zrow" group-by="@GroupName">
            <xsl:value-of select="current-grouping-key()" />
            <xsl:text>amp;#xa;</xsl:text>
            <xsl:value-of select="current-group()/@User" separator="amp;#xa;"/>
            <xsl:text>amp;#xa;</xsl:text>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>
  

Решение XSLT 1.0 основано на методе Мюншиана:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:key name="byGroupName" match="zrow" use="@GroupName"/>
    <xsl:template
        match="zrow[generate-id()=
                    generate-id(key('byGroupName', @GroupName)[1])]">
        <xsl:value-of select="@GroupName"/>
        <xsl:text>amp;#xa;</xsl:text>
        <xsl:apply-templates select="key('byGroupName', @GroupName)" mode="out"/>
    </xsl:template>
    <xsl:template match="zrow" mode="out">
        <xsl:value-of select="@User"/>
        <xsl:text>amp;#xa;</xsl:text>
    </xsl:template>
    <xsl:template match="zrow"/>
</xsl:stylesheet>
  

Комментарии:

1. Не могли бы вы, пожалуйста, предоставить выходные данные в формате HTML?

2. Это работает, если у меня есть поле GroupName, заполненное некоторыми значениями. Не могли бы вы, пожалуйста, обновить код, чтобы управлять, если значения GoupName не имеют в нем никакого значения??

3. @NICK — Есть много-много группирующих вопросов по SO. Это один из наиболее часто задаваемых вопросов. Я бы посоветовал поискать дополнительную информацию о методе Мюнх (если вы используете XSLT 1.0) или группировке в целом. У вас не должно возникнуть проблем с поиском множества хороших примеров. В качестве подсказки, должно быть довольно просто обернуть строки типа <xsl:template match="zrow" mode="out"> другими элементами HTML, например, так: <li><xsl:template match="zrow" mode="out"></li>

4. Привет, спасибо за ваше предложение. Прежде чем опубликовать этот вопрос, я просмотрел все связанные с ним вопросы и примеры, но не смог найти правильного решения. Я думаю, повторное прохождение через это не сильно поможет. В любом случае, спасибо за вашу помощь, это действительно помогло.

5. Всем привет, большое вам спасибо за помощь, и все работает нормально. Только одна проблема. Фактически, моя структура XML-данных выглядит следующим образом: <my:data ItemCount =»5″> <z:row GroupName=»Manager»User =»User1″ /> <z:row GroupName=»Developer»User =»User2″ /> <z:row GroupName=»Manager»User =»User3″ /> <z:row GroupName=»CEO»User =»User4″ /> <z:row GroupName=»CEO»User = » Пользователь5″ /> </my: data> Не могли бы вы, пожалуйста, сказать мне, как я буду обрабатывать «:», потому что, когда я пишу <xsl:key name =»k1″ match =»z: row» use =»@GroupName»/> Это выдает мне ошибку, поскольку префикс z не определен!!