сравнение узлов в xml с xslt

Я преобразовываю данные xml в html-страницу с помощью xslt. Я хочу устранить повторяющиеся данные, которые выглядят следующим образом.

XML-данные

<calendar>
<event>
<date>May 11</date>
<description>Mother's Day</description>
</event>
<event>
<date>May 12</date>
<description>Birthday</description>
</event>
<event>
<date>May 12</date>
<description>Board Meeting</description>
</event>
</calendar>

Мой xslt-код

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>Event Dates </h2>
  <table border="1">
  <tr bgcolor="#9acd32">
  <th>date</th>
  <th>description</th>
  </tr>
  <xsl:for-each select="calendar/event">
  <tr>
  <td><xsl:value-of select="date"/></td>
  <td><xsl:value-of select="description"/></td>
  </tr>
  </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

Мой вывод

date    description
May 11   Mother's Day
May 12   Birthday
May 12   Board Meeting

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

date  description
May 11
  Mother's Day

May 12
  Birthday
  Board Meeting

Пожалуйста, предложите мне код XSLT для изменения . Заранее спасибо .


person Santhosh    schedule 27.08.2012    source источник


Ответы (3)


Я нашел это решение и применил его к вашей проблеме.
Дженни Теннисон написала хорошее и краткое объяснение метода.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text" indent="yes"/>
<xsl:key name="distinct-date" match="/calendar/event/date" use="./text()"/>
<xsl:template match="calendar">
    <xsl:text>date  description
</xsl:text>
    <xsl:for-each select="event/date[generate-id(.) = generate-id(key('distinct-date',.)[1])]">
        <xsl:value-of select="./text()"/>
        <xsl:text>
</xsl:text>
        <xsl:apply-templates select="//event[date/text() = current()/text()]"/>
        <xsl:text>
</xsl:text>
        </xsl:for-each>
    </xsl:template>  

    <xsl:template match="event">
        <xsl:text>    </xsl:text><xsl:value-of select="description/text()"/>
        <xsl:text>
</xsl:text>
    </xsl:template>
</xsl:stylesheet>
person Sbof    schedule 27.08.2012

Это короткое преобразование:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:key name="kDateByVal" match="date" use="."/>

 <xsl:template match="/">
  <xsl:text>date  description</xsl:text>
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match=
  "date[generate-id()=generate-id(key('kDateByVal',.)[1])]">
     <xsl:value-of select="concat('&#xA;',.)"/>
     <xsl:for-each select="key('kDateByVal',.)">
      <xsl:value-of select="concat('&#xA;','  ', ../description)"/>
     </xsl:for-each>
     <xsl:text>&#xA;</xsl:text>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

использует классический метод мюнхенской группировки для преобразования предоставленного XML-документа:< /сильный>

<calendar>
    <event>
        <date>May 11</date>
        <description>Mother's Day</description>
    </event>
    <event>
        <date>May 12</date>
        <description>Birthday</description>
    </event>
    <event>
        <date>May 12</date>
        <description>Board Meeting</description>
    </event>
</calendar>

в желаемый правильный результат:

date  description
May 11
  Mother's Day

May 12
  Birthday
  Board Meeting
person Dimitre Novatchev    schedule 27.08.2012

Единственный способ решить вашу проблему - это так называемая "мюнхенская группировка". Пожалуйста, обратитесь к Muenchian Grouping - группа внутри узла , а не во всем документе, что почти то же самое, что и ваш вопрос, только с именами вместо дней.

Я надеюсь, что это поможет - с уважением, Питер

person Peter    schedule 27.08.2012