XSLT многоуровневая группировка - PullRequest
0 голосов
/ 14 февраля 2019

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

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

Ввод

<Event>
<Registrations>
    <EventRegistration>
        <Participants>
            <Participant>
                <Name>Ticket 1</Name>
            </Participant>
            <Participant>
                <Name>Ticket 2</Name>
            </Participant>
            <Participant>
                <Name>Ticket 3</Name>
            </Participant>
            <Participant>
                <Name>Ticket 4</Name>
            </Participant>
            <Participant>
                <Name>Ticket 5</Name>
            </Participant>
        </Participants>
    </EventRegistration>
    <EventRegistration>
        <Participants>
            <Participant>
                <Name>Ticket 6</Name>
            </Participant>
            <Participant>
                <Name>Ticket 7</Name>
            </Participant>
            <Participant>
                <Name>Ticket 8</Name>
            </Participant>
        </Participants>
    </EventRegistration>
</Registrations>

С текущим преобразованием (прерванодо минимума)

<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:key name="participants" match="Participant" use="'all'" />
<xsl:variable name="groupSize" select="4" />

<xsl:template match="/">
    <document>
        <pages>
            <!--<xsl:apply-templates select="key('participants', 'all')[(position() mod $groupSize) = 1]" mode="multi"/>-->
            <xsl:apply-templates select="key('participants', 'all')" mode="copy"/>
            <!--<xsl:for-each select="key('participants', 'all')[(position() mod $groupSize) = 1]">-->
                <!--<xsl:apply-templates select="." mode="multi"/>-->
            <!--</xsl:for-each>-->
        </pages>
    </document>
</xsl:template>

<xsl:template match="*" mode="copy">
    <xsl:param name="PageNumber" select="position()"/>
    <xsl:apply-templates select=".[(position() mod $groupSize) = 1]" mode="multi">
        <xsl:with-param name="PageNumber" select="$PageNumber"/>
    </xsl:apply-templates>
</xsl:template>

<!--Page-->
<xsl:template match="*" mode="multi">
    <xsl:param name="PageNumber" />
    <page key="{$PageNumber}">
        <xsl:apply-templates select=".|following-sibling::*[position() &lt; $groupSize]" mode="item">
            <xsl:with-param name="PageNumber" select="$PageNumber"/>
        </xsl:apply-templates>
    </page>
</xsl:template>
<!--Tickets-->
<xsl:template match="*" mode="item">
    <xsl:param name="PageNumber"/>
    <ticket key="{$PageNumber}-{position()}">
        <xsl:value-of select="Name"/>
    </ticket>
</xsl:template>

Дает результат

<document>
<pages>
    <page key="1">
        <ticket key="1-1">Ticket 1</ticket>
        <ticket key="1-2">Ticket 2</ticket>
        <ticket key="1-3">Ticket 3</ticket>
        <ticket key="1-4">Ticket 4</ticket>
    </page>
    <page key="2">
        <ticket key="2-1">Ticket 2</ticket>
        <ticket key="2-2">Ticket 3</ticket>
        <ticket key="2-3">Ticket 4</ticket>
        <ticket key="2-4">Ticket 5</ticket>
    </page>
    <page key="3">
        <ticket key="3-1">Ticket 3</ticket>
        <ticket key="3-2">Ticket 4</ticket>
        <ticket key="3-3">Ticket 5</ticket>
    </page>
    <page key="4">
        <ticket key="4-1">Ticket 4</ticket>
        <ticket key="4-2">Ticket 5</ticket>
    </page>
    <page key="5">
        <ticket key="5-1">Ticket 5</ticket>
    </page>
    <page key="6">
        <ticket key="6-1">Ticket 6</ticket>
        <ticket key="6-2">Ticket 7</ticket>
        <ticket key="6-3">Ticket 8</ticket>
    </page>
    <page key="7">
        <ticket key="7-1">Ticket 7</ticket>
        <ticket key="7-2">Ticket 8</ticket>
    </page>
    <page key="8">
        <ticket key="8-1">Ticket 8</ticket>
    </page>
</pages>

Желаемый результат

<document>
<pages>
    <page key="1">
        <ticket key="1-1">Ticket 1</ticket>
        <ticket key="1-2">Ticket 2</ticket>
        <ticket key="1-3">Ticket 3</ticket>
        <ticket key="1-4">Ticket 4</ticket>
    </page>
    <page key="2">
        <ticket key="2-1">Ticket 5</ticket>
        <ticket key="2-2">Ticket 6</ticket>
        <ticket key="2-3">Ticket 7</ticket>
        <ticket key="2-4">Ticket 8</ticket>
    </page>
</pages>

1 Ответ

0 голосов
/ 14 февраля 2019

Я не думаю, что вам нужен ключ здесь, если вы используете постоянное значение для поиска.Простая переменная будет делать

 <xsl:variable name="participants" select="//Participant" />

Затем, чтобы выбрать первого участника для каждой страницы, сделайте это (аналогично одной из ваших закомментированных строк)

 <xsl:apply-templates select="$participants[(position() mod $groupSize) = 1]" mode="page"/>

Затем, чтобы получитьучастники на странице делают это ...

 <xsl:apply-templates select=".|following::Participant[position() &lt; $groupSize]" mode="item">

Обратите внимание на использование following вместо following-sibling, потому что, хотя вы могли выбрать участника из переменной (или ключа), когда вы используетеоператор оси, такой как following-sibling, он ссылается на узлы в реальном документе, а не только на узлы в переменной / ключах.(following-sibling получит только участников с тем же родителем, что и выбранный).

Попробуйте это XSLT

<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:variable name="participants" select="//Participant" />
<xsl:variable name="groupSize" select="4" />

<xsl:template match="/">
    <document>
        <pages>
            <xsl:apply-templates select="$participants[(position() mod $groupSize) = 1]" mode="page"/>
        </pages>
    </document>
</xsl:template>

<!--Page-->
<xsl:template match="*" mode="page">
    <xsl:variable name="PageNumber" select="position()" />
    <page key="{$PageNumber}">
        <xsl:apply-templates select=".|following::Participant[position() &lt; $groupSize]" mode="item">
            <xsl:with-param name="PageNumber" select="$PageNumber"/>
        </xsl:apply-templates>
    </page>
</xsl:template>
<!--Tickets-->
<xsl:template match="*" mode="item">
    <xsl:param name="PageNumber"/>
    <ticket key="{$PageNumber}-{position()}">
        <xsl:value-of select="Name"/>
    </ticket>
</xsl:template>
</xsl:stylesheet>
...