Скажем, у меня есть такие 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.