2011-02-08 21 views
1

XSLTを初めて使用していて、重複するエントリを出力から削除する際に問題があります。 2つの条件に基づいて要素を削除する

例のXML-ファイル:すべての 'ASStamm' から

<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> 

....が、私はこの出力を取得する必要があります

上記と同様のより多くの注文を表しIDは 'ASNR'です。最も古い日付( 'ASGueltigAb')の重複エントリ( 'ASFrk')を削除するものです。

たとえば、エントリ '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つのマークされた行を削除する必要があります。

例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

関連する問題