Удаление элементов на основе двух условий - PullRequest
1 голос
/ 08 февраля 2011

Я новичок в 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», где идентификатором является «ASNR», что необходимо удалить дубликаты записей («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 (009803336), для следующего примера - идентификатора ASNR (040917889)две отмеченные линии должны быть удалены.

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

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

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

1 Ответ

2 голосов
/ 08 февраля 2011

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

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

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