Пропустить элемент в XSLT, если вывод уже содержит аналогичный элемент - PullRequest
0 голосов
/ 29 мая 2020

Скажем, у меня есть такие XML (все, что ниже, было обрезано, чтобы попытаться показать минимальную сумму, необходимую для демонстрации моей проблемы).

<Person>
    <Name>Bob</Name>
    <GroupID>123</GroupID>
</Person>
<Person>
    <Name>Doug</Name>
    <GroupID>123</GroupID>
</Person>
<Person>
    <Name>Melinda</Name>
    <GroupID>123</GroupID>
</Person>
<Person>
    <Name>Kathy</Name>
    <GroupID>22</GroupID>
</Person>
<Person>
    <Name>Mark</Name>
    <GroupID>22</GroupID>
</Person>
<Person>
    <Name>Roberto</Name>
    <GroupID>33</GroupID>
</Person>
<Person>
    <Name>Carlos</Name>
</Person>
<Person>
    <Name>Sasha</Name>
</Person>

Я хочу иметь возможность сгруппировать их записей по их GroupID, поэтому результат должен быть примерно таким:

<Persons>
    <Group>
        <GroupID>123</GroupID>
        <Person>
            <Name>Bob</Name>
        </Person>
        <Person>
            <Name>Doug</Name>
        </Person>
        <Person>
            <Name>Melinda</Name>
        </Person>
    </Group>
    <Group>
        <GroupID>22</GroupID>
        <Person>
            <Name>Kathy</Name>
        </Person>
        <Person>
            <Name>Mark</Name>
        </Person>
    </Group>
    <Group>
        <GroupID>33</GroupID>
        <Person>
            <Name>Roberto</Name>
        </Person>
    </Group>
    <Group>
        <Person>
            <Name>Carlos</Name>
        </Person>
    </Group>
    <Group>
        <Person>
            <Name>Sasha</Name>
        </Person>
    </Group>
</Persons>

То, что я делаю, выглядит примерно так:

 <Persons>
    <xsl:for-each select="Person">
        <xsl:choose>
            <xsl:when test="GroupID != ''">
                <xsl:variable name="groupId" select="GroupID"/>
                <Group>
                    <GroupID>
                        <xsl:value-of select="groupId"/>
                    </GroupID>
                    <xsl:for-each select="../Person[GroupID = groupId]">
                        <xsl:call-template name="PersonData"/>
                    </xsl:for-each>
                </Group>
            </xsl:when>
            <xsl:otherwise>
                <Group>
                    <xsl:call-template name="PersonData"/>
                </Group>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</Persons>

Проблема в том, что каждая группа дублируется для столько людей, сколько в группе. Что я действительно хотел бы сделать, так это проверить, обработал ли я «текущий» GroupID уже или нет - таким образом я могу сказать: «Хорошо, этот GroupID уже был обработан, так что пропустите его».

EDIT: здесь используется XSLT 2 с Xalan, поэтому на самом деле XSLT 1.

EDIT2: Возможно, что атрибут GroupID может отсутствовать для одной или нескольких записей. В таких случаях каждая из этих записей должна получить отдельную группу без идентификатора GroupID.

1 Ответ

0 голосов
/ 29 мая 2020

Вы можете сделать это так:

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

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <Persons>
            <xsl:for-each-group select="//Person" group-by="GroupID">
                <Group>
                    <GroupID><xsl:value-of select="current-grouping-key()"/></GroupID>
                    <xsl:for-each select="current-group()">
                        <Person>
                            <Name><xsl:value-of select="Name"/></Name>
                        </Person>
                    </xsl:for-each>
                </Group>
            </xsl:for-each-group>
        </Persons>
    </xsl:template>

</xsl:stylesheet>

Посмотрите, как это работает: https://xsltfiddle.liberty-development.net/a9HjZd

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...