XSLT извлекает первое уникальное значение - PullRequest
2 голосов
/ 20 марта 2012

Я пытаюсь получить первый уникальный набор из 2 атрибутов.

Я ищу имя каждого студента по его первой уникальной группе. Если для студента первая группа уже занята для любого студента, должна быть указана следующая уникальная группа. Я разместил свой XML и ожидаемый результат XML.

Мне нужны операторы XSLT, чтобы получить этот результат (Версия 1.0). Спасибо.

Вот моя структура XML

<Socrates>
<Student name='Aristotle' group='1' />
<Student name='Aristotle' group='2' />
<Student name='Aristotle' group='3' />
<Student name='Aristotle' group='4' />

<Student name='Plato' group='1' />
<Student name='Plato' group='2' />
<Student name='Plato' group='3' />

<Student name='Xenophon' group='4' />
<Student name='Xenophon' group='5' />
<Student name='Xenophon' group='6' />

<Student name='Critias' group='1' />
<Student name='Critias' group='2' />
<Student name='Critias' group='3' />    
<Student name='Critias' group='4' />
<Student name='Critias' group='5' />
<Student name='Critias' group='6' />
   </Socrates>

Результат XML

<Socrates>
    <Student name='Aristotle' group='1' />
<Student name='Plato' group='2' />
<Student name='Xenophon' group='4' />
<Student name='Critias' group='3' />
</Socrates>

1 Ответ

2 голосов
/ 22 марта 2012

Другой немного другой подход (хотя и не обязательно лучший) заключается в передаче параметра каждому совпадению student , которое содержит разделенные запятыми атрибуты group , которые уже были выведены,Каждый раз, когда вы сопоставляете студента , вы проверяете, входит ли его группа в его параметр, и если не выводится студент, и получаете следующую группу, добавляя текущую группу к параметру.

Вот XSLT, который я прокомментировал, чтобы попытаться объяснить вещи лучше

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output indent="yes"/>

   <xsl:template match="Socrates">
      <Socrates>
         <xsl:apply-templates select="Student[1]"/>
      </Socrates>
   </xsl:template>

   <xsl:template match="Student">
      <!-- Parameter containin comma-delimited list of currently output groups -->
      <xsl:param name="groupList" select="','" />
      <xsl:choose>
         <!-- Has the group already been output? -->
         <xsl:when test="contains($groupList, concat(',', @group, ','))">
            <!-- If so, move on to next student record -->
            <xsl:apply-templates select="following-sibling::Student[1]">
               <xsl:with-param name="groupList" select="$groupList" />
            </xsl:apply-templates>
         </xsl:when>
         <!-- Group has not already been output -->
         <xsl:otherwise>
            <!-- Output the record -->
            <xsl:copy-of select="." />

            <!-- Get the next student with a different name -->
            <xsl:apply-templates select="following-sibling::Student[@name!=current()/@name][1]">
               <xsl:with-param name="groupList" select="concat($groupList, @group, ',')" />
            </xsl:apply-templates>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

При применении к вашему образцу XML выдается следующее:

<Socrates>
   <Student name="Aristotle" group="1" />
   <Student name="Plato" group="2" />
   <Student name="Xenophon" group="4" />
   <Student name="Critias" group="3" />
</Socrates>

Обратите внимание, что это предполагает student элементы всегда упорядочены по имени во входном XML.

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