Avatar billede lazy_warrior Nybegynder
17. december 2004 - 15:39 Der er 5 kommentarer og
1 løsning

Bruge Key til accumulering, selvom en node mangler

Hej folkens
Jeg troede jeg avde fået dette til at virke, men det gør det ikke alliegvel :( ikke helt

Jeg har en lille XML fil indeholdende en fejlrapport:

<?xml version="1.0" encoding="iso-8859-1"?>
<report>
  <errors>
    <error>
      <line>1</line>
      <message>fejlbeskrivelse 1</message>
      <code>1</code>
    </error>
    <error>
      <line>2</line>
      <message>fejlbeskrivelse 2</message>
      <code>1</code>
    </error>
    <error>
      <line>3</line>
      <message>fejlbeskrivelse 3</message>
    </error>
    <error>
      <line>4</line>
      <message>fejlbeskrivelse 4</message>
    </error>
  </errors>
</report>

Nogle gange indeholder en besked en fejlkode, andre gange ikke. Beskeden behøver ikke være den samme selvom fejlkoden er den samme.

Jeg vil så gerne lave en sammentælling af antallet af fejl med samme kode, samt en optælling af alle fejl uden nogen kode.

Sammentællingen har jeg lavet, dog viser den en ny indgang for hvert tag hvor der ikke er nogen kode tag.

Jeg kan ikke ændre i XML filen, det er ikke en jeg selv laver :( (den er her i en skrabet version)

Min xslfil ser således ud:
<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- the key definition is the grouping -->

<xsl:key name="errorCode" match="error" use="code"/>

<xsl:template match="/report">
<html>
<body>

<xsl:apply-templates select="errors" mode="accumulatedErrors"/>

</body>

</html>
</xsl:template>

<xsl:template match="errors" mode="accumulatedErrors">
<h3>Accumulated Errors</h3>
<table border="1">
    <tr>
        <th>Error code</th>
        <th>Occurences</th>
    </tr>

<!-- now you take the first row of every group -->

<xsl:for-each select="error[count(.|key('errorCode',code)[1]) = 1]">
    <tr>
        <td>
            <!-- put out the errocode -->
            <xsl:value-of select="code"/>
        </td>
        <td>
            <!-- and the sum of all rows with this event -->
            <xsl:value-of select="count(key('errorCode',code))"/>
        </td>
    </tr>
</xsl:for-each>
</table>
</xsl:template>

</xsl:stylesheet>
Avatar billede lazy_warrior Nybegynder
17. december 2004 - 15:41 #1
Jeg ved ikke om jeg kom til at abonnere når man opretter.
Avatar billede atoft Nybegynder
19. december 2004 - 20:38 #2
øv havde lige skrevet en mega stil, men kunne ikke få lov submitte den :-(

Derfor her den korte udgave:

ret

<xsl:for-each select="error[count(.|key('errorCode',code)[1]) = 1]">

til

<xsl:for-each select="error[code and count(.|key('errorCode',code)[1]) = 1]">
Avatar billede atoft Nybegynder
19. december 2004 - 20:39 #3
hvis du ønsker uddygning, så bare sig til. Jeg gad bare ikke skrive det igen hvis du var ligegladt.
Avatar billede lazy_warrior Nybegynder
20. december 2004 - 08:01 #4
Jeg vil meget gerne have en lille forklaring. Det virker efter hensigten, nu skal jeg bare have talt de error tags sammen der ikke har nogen fejlkode ;) men burde være muligt.
Avatar billede lazy_warrior Nybegynder
20. december 2004 - 08:16 #5
Jeg satte denne linie ind for at tælle alle dem der ikke havde noget code tag (Det kunne sikkert gøres mere effektivt, men ja det eneste jeg lige kom på)

<xsl:value-of select="(count(/report/errors/error) - count(/report/errors/error[name(code)]))"/>
Avatar billede atoft Nybegynder
20. december 2004 - 10:20 #6
Den sidste

<xsl:value-of select="(count(/report/errors/error) - count(/report/errors/error[name(code)]))"/>

kan laves om til den lidt mere simple og billigere

<xsl:value-of select="count(/report/errors/error[not(code)]) "/>

Problemet med den føste løsning var at key ikke indeholdt error elementer uden code. Derfor ville din

<xsl:for-each select="error[count(.|key('errorCode',code)[1]) = 1]"> altid give en for de errors som ikke havde nogen code. Ideen med ovenstående er nemli, at man tager den første nøgle ud af key, som matcher den aktuelle node. Join'er de 2 noder sammen og vis det er samme node vil en count kun give en da en join af 2 gange den samme node kun vil returne noden en gang. Fx. er den aktuelle node ikke lig med den første i key'en vil join'en returne 2 forskellige node og dermed give en count på 2. Problemet opstår så for de noder som slet ikke er med i key, altså de error elementer uden code. De kan ikke findes i key'en og derfor vil deres count altid være 1. That simple :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester