XSLT多级分组

时间:2019-02-14 10:15:42

标签: xslt xslt-1.0

提前感谢您的宝贵时间。我尝试并搜索了几种解决方案,但无济于事。

我想打印出票。假设其中4个适合一页。但是一张票可能包含多于或少于4张票。我想将所有票分成4组,但是根据我目前的翻译,我在页面上空白。如果我留在一个人内,我设法使其正常工作,这是使我的头部受伤atm的倍数。

输入

<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 :(得分:0)

我认为您不需要此处的键,如果您使用常量值进行查找,则不需要。一个简单的变量就可以了

 <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>