XSLT подгруппа - PullRequest
       10

XSLT подгруппа

0 голосов
/ 22 мая 2018

Мне нужна помощь с подгруппой в XSLT 1.0.У меня есть следующий ввод XML

<Items>
<Item>
    <DAYRATE>12.00</DAYRATE>
    <WEEKRATE>13.00</WEEKRATE>
    <MONTHRATE>14.00</MONTHRATE>
    <MAJOR>Major 1</MAJOR>
    <MINOR>Minor 1</MINOR>
    <NAME>Name 1</NAME>
</Item>
<Item>
    <DAYRATE>15.00</DAYRATE>
    <WEEKRATE>16.00</WEEKRATE>
    <MONTHRATE>17.00</MONTHRATE>
    <MAJOR>Major 2</MAJOR>
    <MINOR>Minor 2</MINOR>
    <NAME>Name 1</NAME>
</Item>
<Item>
    <DAYRATE>25.00</DAYRATE>
    <WEEKRATE>26.00</WEEKRATE>
    <MONTHRATE>27.00</MONTHRATE>
    <MAJOR>Major 2</MAJOR>
    <MINOR>Minor 2</MINOR>
    <NAME>Name 2</NAME>
</Item></Items>

Мой желаемый вывод будет выглядеть примерно так:

<Items>
<Item>
    <Major>Major 1</Major>
    <Detail>
        <Minor>Minor 1</Minor>
        <Info>
            <Name>Name 1</Name>
            <DayRate>12.00</DayRate>
            <WeekRate>13.00</WeekRate>
            <MonthRate>14.00</MonthRate>
        </Info>
    </Detail>
</Item>
<Item>
    <Major>Major 2</Major>
    <Detail>
        <Minor>Minor 2</Minor>
        <Info>
            <Name>Name 1</Name>
            <DayRate>15.00</DayRate>
            <WeekRate>16.00</WeekRate>
            <MonthRate>17.00</MonthRate>
        </Info>
        <Info>
            <Name>Name 2</Name>
            <DayRate>25.00</DayRate>
            <WeekRate>26.00<WeekRate>
            <MonthRate>27.00</MonthRate>
        </Info>
    </Detail>
</Item>

По сути, я хотел бы сначала сгруппировать его по основным, а затем поНезначительный.Ищите решение XSLT 1.0.

Буду признателен за любую помощь.

Спасибо.

Я пробовал использовать XSLT, но небольшая группировка не работает.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0"/>

<xsl:key name="minor-cat" match="/Items/Item" use="MINOR/text()"/>

<xsl:template match="/Items">
    <Items>
        <xsl:for-each select="key('minor-cat', Item/MINOR/text())">
            <Item>
                <Major>
                    <xsl:value-of select="MAJOR/text()"/>
                </Major>
                <Detail>
                    <Minor>
                        <xsl:value-of select="MINOR/text()"/>
                    </Minor>
                    <Info>
                        <Name>
                            <xsl:value-of select="NAME/text()"/>
                        </Name>
                        <DayRate>
                            <xsl:value-of select="DAYRATE/text()"/>
                        </DayRate>
                        <WeekRate>
                            <xsl:value-of select="WEEKRATE/text()"/>
                        </WeekRate>
                        <MonthRate>
                            <xsl:value-of select="MONTHRATE/text()"/>
                        </MonthRate>
                    </Info>
                </Detail>
            </Item>
        </xsl:for-each>
    </Items>
</xsl:template>

Ответы [ 2 ]

0 голосов
/ 23 мая 2018
<xsl:template match="Items">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Item">
        <xsl:copy>
            <xsl:apply-templates select="MAJOR"/>
            <xsl:apply-templates select="MINOR"/>
            <xsl:apply-templates select="NAME"/>
            <xsl:apply-templates select="DAYRATE|WEEKRATE|MONTHRATE"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="MAJOR">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="MINOR">
        <DETAIL>
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
            <xsl:apply-templates select=" following-sibling::NAME"/>
        </DETAIL>
    </xsl:template>
    <xsl:template match="NAME">
        <INFO>
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
            <xsl:apply-templates select="preceding-sibling::DAYRATE|preceding-sibling::WEEKRATE|preceding-sibling::MONTHRATE"/>
        </INFO>
    </xsl:template>
    <xsl:template match="DAYRATE">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="WEEKRATE">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="MONTHRATE">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>
Check it if it is useful for you
0 голосов
/ 23 мая 2018

В XSLT-1.0 для этого нужно использовать Muenchian Grouping с составным ключом .

Вам нужно всего лишь внести четыре изменения в свой XSLT:

  • один на key создание составного ключа
  • один на for-each для реализации мюнхенская группировка
  • создание ключа сортировки типа number, чувствительного к десятичному формату, из составного ключа
  • добавление этого ключа сортировки к sort выводу с помощью числа, созданного выше

Это полный XSLT-1.0:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0"/>

<!-- Modified to use a composite key -->
<xsl:key name="minor-cat" match="/Items/Item" use="concat(MAJOR/text(),'.',MINOR/text())"/>          

<xsl:template match="/Items">
    <Items>
        <!-- Modified to use Muenchian Grouping -->
        <xsl:for-each select="Item[generate-id() = generate-id(key('minor-cat', concat(MAJOR/text(),'.',MINOR/text()))[1])]">   
            <!-- Added to sort by key -->
            <xsl:sort select="number(concat(substring-after(MAJOR/text(),' '),'.',substring-after(MINOR/text(),' ')))" data-type="number" /> 
            <!-- Process all elements with the same Major/Minor value -->
            <xsl:for-each select="key('minor-cat', concat(MAJOR/text(),'.',MINOR/text()))">
                <Item>
                    <Major>
                        <xsl:value-of select="MAJOR/text()"/>
                    </Major>
                    <Detail>
                        <Minor>
                            <xsl:value-of select="MINOR/text()"/>
                        </Minor>
                        <Info>
                            <Name>
                                <xsl:value-of select="NAME/text()"/>
                            </Name>
                            <DayRate>
                                <xsl:value-of select="DAYRATE/text()"/>
                            </DayRate>
                            <WeekRate>
                                <xsl:value-of select="WEEKRATE/text()"/>
                            </WeekRate>
                            <MonthRate>
                                <xsl:value-of select="MONTHRATE/text()"/>
                            </MonthRate>
                        </Info>
                    </Detail>
                </Item>
            </xsl:for-each>
        </xsl:for-each>
    </Items>
</xsl:template>
</xsl:stylesheet>
...