große Probleme mit substring() und Vergleiche
Carsten
- xsl
0 Thomas J.S.0 Carsten
Hallo,
ich habe ein großes Problem. Damit ich das Problem erläutern kann, poste ich einmal mei xml Files, eine XSLT Anweisung und das HTML Ergebnis. Vielleicht findet ja jemand eine Lösung.
Ich habe folgende xml Seite:
<testResults>
<sampleResult timeStamp="23.04.2004 11:24:41" dataType="text" threadName="Testszenario 1-1" label="User1 Start" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:41" dataType="text" threadName="Testszenario 1-1" label="User1 Login" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:44" dataType="text" threadName="Testszenario 1-2" label="User2 Start" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:44" dataType="text" threadName="Testszenario 1-2" label="User2 Login" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:41" dataType="text" threadName="Testszenario 1-1" label="User1 Aktion1" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:45" dataType="text" threadName="Testszenario 1-1" label="User1 Aktion2" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:45" dataType="text" threadName="Testszenario 1-1" label="User1 Aktion3" success="false">
<assertionResult failureMessage="" error="false" failure="false"/>
<assertionResult failureMessage="Test failed, text expected not to contain /true/" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:47" dataType="text" threadName="Testszenario 1-2" label="User2 Aktion1" success="true">
<assertionResult failureMessage="" error="false" failure="false"/>
</sampleResult>
<sampleResult timeStamp="23.04.2004 11:24:47" dataType="text" threadName="Testszenario 1-2" label="User2 Aktion2" success="false">
<assertionResult failureMessage="" error="false" failure="false"/>
<assertionResult failureMessage="Test failed, text expected not to contain /true/" error="false" failure="true"/>
</sampleResult>
</testResults>
Nun habe ich das Problem, dass ich die User mir mittels der substring Funktion herausziehe und in eine html Tabelle lege. Aber, egal wie ich es mache, ich bekomme leider nicht nur einmal User1 und USer2 sondern, oftmals halt so, wie sie in den labels stehen (User1, User1, User2, User2). Dann habe ich durch einen "threadName" Vergleich es wenigstens so geschafft, dass nur pro threadName die User ausgegeben werden. Ich möchte aber generell, beim ersten Vorkommen eines Users ihn ausgeben und danach nicht noch einmal, so dass ich eine Tabelle erhalte, die nur die benutzten User enthält.
Meine momentane xslt Anweisung so so aus:
<xsl:template name="user">
<h1>Benutzte User</h1>
<xsl:variable name="label" select="@label" />
<table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
<tr valign="top">
<th> User </th>
</tr>
<xsl:for-each select="/testResults/sampleResult[not(@label = preceding::*/@label)]">
<xsl:variable name="user" select="substring(@label,1,6)" />
<xsl:if test="@threadName= preceding::*/@threadName">
<xsl:variable name="user2" select="substring(@label,1,6)" />
<td><xsl:value-of select="substring(@label,1,6)" /></td>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
Das Ergebnis schaut dann so aus:
<h1>Benutzte User</h1>
<table width="95%" cellspacing="2" cellpadding="5" border="0" class="details">
<tr valign="top">
<th> User </th>
</tr>
<td>User1 </td><td>User2 </td><td>User1 </td><td>User1 </td><td>User1 </td><td>User2 </td><td>User2 </td>
</table>
Ich hoffe mir kann jemand helfen, dieses Probelm zu lösen.
Vielen Dank.
Gruß,
Carsten
Hallo,
Nun habe ich das Problem, dass ich die User mir mittels der substring Funktion herausziehe und in eine html Tabelle lege. Aber, egal wie ich es mache, ich bekomme leider nicht nur einmal User1 und USer2 sondern, oftmals halt so, wie sie in den labels stehen (User1, User1, User2, User2). Dann habe ich durch einen "threadName" Vergleich es wenigstens so geschafft, dass nur pro threadName die User ausgegeben werden. Ich möchte aber generell, beim ersten Vorkommen eines Users ihn ausgeben und danach nicht noch einmal, so dass ich eine Tabelle erhalte, die nur die benutzten User enthält.
Meine momentane xslt Anweisung so so aus:
<xsl:variable name="user" select="substring(@label,1,6)" />
Das sit so oder so nicht günstig, was ist wenn der Username nicht 5 sonder 6 Zeichen hat?
Überlege dir was du brauchst: du willst einmal alle @label auf den Usernamen überprüfen.
Also versuchst du eine Gruppe zu erstellen:
<xsl:key name="user" match="sampleResult" use="substring-before(@label, ' ')" />
Dieser key enthält nun alle sampleResult-Element und für jeden nimmt er als Wert von @label die Zeichen vor einem Leerzeichen.
Na fein, aber du willst nur immer ein Mitgleid der Gruppe, und zwar das immer das erste von den identischen Usernamen.
Du muss also erstens den ersten Mitgleid der Gruppe ausfindig machen und dann ein vergleich für jeden der sampleResult-Elemente durchführen:
<xsl:for-each select="sampleResult[generate-id() = generate-id(key('user', substring-before(@label, ' '))[1])]">
Das macht nun folgendes:
<xsl:for-each select="sampleResult[generate-id()
Für jeden sampleResult-Element wird eine ID generiert.
= generate-id(key('user', substring-before(@label, ' '))[1])]">
Dann wird eine ID für für die Mitglieder der Gruppe generiert, die Gruppe haben wir ja mit dem xsl:key erfasst, also nützen wird diesen key hier, als Vergleichbasis dient das "substring-before(@label, ' ')" aus dem gerade aktuellen sampleResult. Und weil wir nur das erste Vorkommen mit dem einem identischen Wert brauchen, nehmen wir die erste Position: [1]
Etwas kompliziert ich weiss.
Und so sieht es dann aus, wenn das alles zusammengefasst wird:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="user" match="sampleResult" use="substring-before(@label, ' ')" />
<xsl:template match="/">
<html>
<head>
<title>Untitled</title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="testResults">
<xsl:call-template name="user" />
</xsl:template>
<xsl:template name="user">
<xsl:variable name="username" select="sampleResult[generate-id() = generate-id(key('user', substring-before(@label, ' '))[1])]" />
<h1>Benutzte User</h1>
<table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
<tr valign="top">
<th colspan="{count($username)}"> User </th>
</tr>
<tr>
<xsl:for-each select="$username">
<td><xsl:value-of select="substring-before(@label, ' ')" /></td>
</xsl:for-each>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
Ich habe den Verglich in die Variable gesteckt, damit auch dein HTML korrekt bleibt (so kannst du das colspan="" auch berechnen.)
Grüße
Thomas
Hallo,
Etwas kompliziert ich weiss.
jo, wahrhaftig etwas kompliziert. Aber nun weiss ich es ja, DANKE!!. So kann man immer doppelte Elemente ausschließen, über diese key und generate-id Funktion; braucht man bestimmt öfters.
Was machst du eigentlich beruflich? Du antwortest immer prompt und korrekt. Ein xslt Guru....hehe.....auf jeden Fall vielen Dank.
Gruß,
Carsten
Hallo,
Etwas kompliziert ich weiss.
jo, wahrhaftig etwas kompliziert. Aber nun weiss ich es ja, DANKE!!. So kann man immer doppelte Elemente ausschließen, über diese key und generate-id Funktion; braucht man bestimmt öfters.
Es gibt auch im Archiv schon einige Beiträge mit verschiedenen Anwendungsfällen für Gruppierung mit keys.
Was machst du eigentlich beruflich?
XML/XSL Entwicklung ;-)
»»Du antwortest immer prompt und korrekt.
Danke.
Grüße
Thomas