2011-02-08 5 views
1

Я новичок в XSLT и имею проблему с удалением повторяющихся записей с выхода.Извлечение элементов на основе двух условий

Пример XML-файл:

<Datenaustausch> 
<Meldung> 
    <Anfallstelle> 
     <AS> 
      <ASStamm> 
       <ASNR>009803336</ASNR> 
       <ASENF>false</ASENF> 
       <ASInaktiv>false</ASInaktiv> 
      </ASStamm> 
      <ASDaten> 
       <ASMeldung> 
        <ASGueltigAb>2003-04-25</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
       <ASMeldung> 
        <ASGueltigAb>2008-05-15</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
       <ASMeldung> 
        <ASGueltigAb>2010-08-20</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>40x</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
      </ASDaten> 
     </AS> 
     <AS> 
      <ASStamm> 
       <ASNR>031630116</ASNR> 
       <ASENF>false</ASENF> 
       <ASInaktiv>false</ASInaktiv> 
      </ASStamm> 
      <ASDaten> 
       <ASMeldung> 
        <ASGueltigAb>2009-04-21</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>400</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
      </ASDaten> 
     </AS> 
     <AS> 
      <ASStamm> 
       <ASNR>040917889</ASNR> 
       <ASENF>false</ASENF> 
       <ASInaktiv>false</ASInaktiv> 
      </ASStamm> 
      <ASDaten> 
       <ASMeldung> 
        <ASGueltigAb>2007-11-15</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>400</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>42x</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
       <ASMeldung> 
        <ASGueltigAb>2009-01-19</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>400</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>42x</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
       <ASMeldung> 
        <ASGueltigAb>2010-06-25</ASGueltigAb> 
        <ASMldData> 
         <ASLizData> 
          <ASFrk>400</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>42x</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
         <ASLizData> 
          <ASFrk>8xx</ASFrk> 
          <ASLizGrad>100</ASLizGrad> 
          <ASAntVerp>100</ASAntVerp> 
         </ASLizData> 
        </ASMldData> 
       </ASMeldung> 
      </ASDaten> 
     </AS> 
        <AS> 
        .... 
        </AS> 
     </Anfallstelle> 
</Meldung> 
</Datenaustausch> 

.... представляет больше приказов же, что и выше

Мне нужно, чтобы получить этот результат:

От каждый 'ASStamm', где ID - это «ASNR». I, чтобы удалить дубликаты записей («ASFrk») с самой старой датой («ASGueltigAb»).

Например, первый 'AS' запись должна выглядеть следующим образом:

 <tr> 
      <td>009803336</td> 
      <td>8xx</td> 
      <td>100</td> 
      <td>100</td> 
      <td>2008-05-15</td> 
     </tr> 
     <tr> 
      <td>009803336</td> 
      <td>40x</td> 
      <td>100</td> 
      <td>100</td> 
      <td>2010-08-20</td> 
     </tr> 

Дубликат запись (с 'ASFrk' (8xx) и старой датой 'ASGueltigAb' (2003-04-25)) был удален.

В настоящее время я использую это «решение» для преобразования xml в таблицу html, но без удаления повторяющихся записей.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>XML</title> 
      </head> 
      <body> 
       <table border="1"> 
        <tr> 
         <th>ASNR</th> 
         <th>ASFrk</th> 
         <th>ASLizGrad</th> 
         <th>ASAntVerp</th> 
         <th>ASGueltigAb</th> 
        </tr> 
        <xsl:for-each select="/Datenaustausch/Meldung/Anfallstelle/AS"> 
         <xsl:sort select="ASStamm/ASNR" data-type="number"/> 
         <xsl:for-each select="ASDaten/ASMeldung"> 
          <xsl:sort select="ASMldData/ASLizData/ASFrk" order="descending"/> 
          <xsl:sort select="ASGueltigAb" order="descending" /> 
          <tr> 
           <td> 
            <xsl:value-of select="parent::*/parent::AS/ASStamm/ASNR"/> 
           </td> 
           <td> 
            <xsl:value-of select="ASMldData/ASLizData/ASFrk"/> 
           </td> 
           <td> 
            <xsl:value-of select="ASMldData/ASLizData/ASLizGrad"/> 
           </td> 
           <td> 
            <xsl:value-of select="ASMldData/ASLizData/ASAntVerp"/> 
           </td> 
           <td> 
            <xsl:value-of select="ASGueltigAb"/> 
           </td> 
          </tr> 
         </xsl:for-each> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

HTML-выход:

Пример 1: http://img152.imageshack.us/i/xmlex.jpg/

Заметная линия должна быть удалена для 'ASNR'-ID (009803336), для следующего примера' ASNR'- ID (040917889) две отмеченные строки должны быть удалены.

Пример 2: http://img710.imageshack.us/i/xmlex2.jpg/

Я думаю, что есть решение с использованием «Muenchian группировки», но я не знаю, как.

Может кто-нибудь помочь мне получить решение с помощью XSLT 1.0?

ответ

2

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="kASLizDataByASNR-ASFrk" 
      match="ASLizData" 
      use="concat(preceding::ASNR[1],'+',ASFrk)"/> 
    <xsl:template match="text()"/> 
    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>XML</title> 
      </head> 
      <body> 
       <table border="1"> 
        <tr> 
         <th>ASNR</th> 
         <th>ASFrk</th> 
         <th>ASLizGrad</th> 
         <th>ASAntVerp</th> 
         <th>ASGueltigAb</th> 
        </tr> 
        <xsl:apply-templates/> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
    <xsl:template match="ASLizData[ 
          count(
           .|key('kASLizDataByASNR-ASFrk', 
            concat(preceding::ASNR[1],'+',ASFrk) 
           )[1] 
          ) = 1 
         ]"> 
     <xsl:variable name="vASNR" select="preceding::ASNR[1]"/> 
     <xsl:for-each select="key('kASLizDataByASNR-ASFrk', 
            concat($vASNR,'+',ASFrk) 
          )"> 
      <xsl:sort select="../../ASGueltigAb" order="descending"/> 
      <xsl:if test="position()=1"> 
       <tr> 
        <td> 
         <xsl:value-of select="$vASNR"/> 
        </td> 
        <xsl:apply-templates mode="cell"/> 
        <td> 
         <xsl:value-of select="../../ASGueltigAb"/> 
        </td> 
       </tr> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="ASLizData/*" mode="cell"> 
     <td> 
      <xsl:value-of select="."/> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<html> 
    <head> 
     <META http-equiv="Content-Type" content="text/html; charset=UTF-16"> 
     <title>XML</title> 
    </head> 
    <body> 
     <table border="1"> 
      <tr> 
       <th>ASNR</th> 
       <th>ASFrk</th> 
       <th>ASLizGrad</th> 
       <th>ASAntVerp</th> 
       <th>ASGueltigAb</th> 
      </tr> 
      <tr> 
       <td>009803336</td> 
       <td>8xx</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2010-08-20</td> 
      </tr> 
      <tr> 
       <td>009803336</td> 
       <td>40x</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2010-08-20</td> 
      </tr> 
      <tr> 
       <td>031630116</td> 
       <td>400</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2009-04-21</td> 
      </tr> 
      <tr> 
       <td>031630116</td> 
       <td>8xx</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2009-04-21</td> 
      </tr> 
      <tr> 
       <td>040917889</td> 
       <td>400</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2010-06-25</td> 
      </tr> 
      <tr> 
       <td>040917889</td> 
       <td>42x</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2010-06-25</td> 
      </tr> 
      <tr> 
       <td>040917889</td> 
       <td>8xx</td> 
       <td>100</td> 
       <td>100</td> 
       <td>2010-06-25</td> 
      </tr> 
     </table> 
    </body> 
</html> 

Примечание: Ключ от ASNR и ASFrk. Максимум for-each.

+0

+1 для хорошего ответа. –

+0

+1 для 'kASLizDataByASNR-ASFrk' :) – Flack

+0

Благодарим за решение! – WilliE

Смежные вопросы