Removing elements based on two conditions
I am new to XSLT and have a problem with removing duplicate entries from the output.
The example XML-File:
<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&g开发者_开发问答t;
<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>
....
represents more orders of same as above
I need to get this output:
From every 'ASStamm' where the ID is the 'ASNR' I what to remove the duplicate entries ('ASFrk') with the oldest date ('ASGueltigAb').
For example the first 'AS' entry should look like this:
<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>
The duplicate entry (with 'ASFrk' (8xx) and the old date 'ASGueltigAb' (2003-04-25)) was removed.
At the moment I use this "solution" to transform the xml to a html table, but without removing the duplicate entries.
<?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 Output:
Example 1: http://img152.imageshack.us/i/xmlex.jpg/
The marked line should be removed for the 'ASNR'-ID (009803336), for the next example 'ASNR'-ID (040917889) the two marked lines should be removed.
Example 2: http://img710.imageshack.us/i/xmlex2.jpg/
I think there is a solution with the use of the "Muenchian grouping", but i don´t know how.
Can someone please help me to get a solution using XSLT 1.0?
This stylesheet:
<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>
Output:
<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>
Note: Key by ASNR and ASFrk. Maximum for-each
.
精彩评论