Announcement

Collapse
No announcement yet.

Adressierung innerhalb Gruppen eines Turnierverlauf

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Adressierung innerhalb Gruppen eines Turnierverlauf

    Hallo zusammen,
    gegeben ist eine xml datei, welche Ergebnisse eines Turnierverlaufs darstellt. Der Aufbau der xml-datei ist in etwa so:
    Code:
    <turnier>
    <gruppe ordnung="1">
    <spiel nr="1">
    <mannschaft kürzel="a" tore="2" punkte="3"/>
    <mannschaft kürzel="b" tore="1" punkte="0"(>
    </spiel>
    <spiel nr="2"
    <mannschaft kürzel="a" tore="1" punkte="1"/>
    <mannschaft kürzel="c" tore="1" punkte="1"/>
    </spiel>
    <!-- x weitere Spiele -->
    </gruppe>
    <!-- x weitere Gruppen -->
    </turnier>
    Ich möchte mittels xslt aus den angegebenen Paarungen eine Gruppen-Tabelle errechnen lassen.

    Dafür benötige ich Anregungen wie der Aufbau der xslt aussehen könnte. Meine ersten Versuche waren mit <xsl:for-each ...> das erste Problem war, dass die Spiele innerhalb der Gruppe auch ungeordnet sein können und die Mannschaftskürzel in den anderen Gruppen nicht gleich sind, daher brauche ich irgendeine Möglichkeit die Spiele einer Mannschaft mit Kürzel zu finden und die Argumente und Tore und Punkte für alle Spiele zusammenzufassen - aber wie kann ich das passend adressieren?

    Vielen Dank schonmal...

    Vielleicht füge ich das noch hinzu, die xslt datei stelle ich mir bisher so vor:
    Code:
    <xsl:for-each-group select="/turnier/gruppe" group-by="@ordnung" >
                    <h2>Tabelle Gruppe <xsl:value-of select="@ordnung"/></h2>
                    <table>
                        <tr><th>Position</th><th> Team </th><th> Tore </th><th>Punkte</th></tr>
                        <tr><th>1.</th>
                            <th><xsl:value-of select="//@kürzel"/></th>
    <!-- wobei das so natürlich nicht funktioniert -->
                            <th>...tore...</th>
                            <th>...punkte...</th>
                        </tr>
    Zuletzt editiert von xmapz; 17.09.2010, 17:10.

  • #2
    Hier ist mal ein XSLT 2.0 Beispiel, das für eine Gruppe eine Tabelle berechnet:
    Code:
    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="2.0">
      
      <xsl:output method="html" indent="yes"/>
      
      <xsl:template match="/">
        <html lang="de">
          <head>
            <title>Tabellen</title>
          </head>
          <body>
            <h1>Tabellen</h1>
            <xsl:apply-templates/>
          </body>
        </html>
      </xsl:template>
      
      <xsl:template match="gruppe">
        <h2>Tabelle Gruppe <xsl:value-of select="@ordnung"/></h2>
        <table>
          <thead>
            <tr>
              <th>Position</th>
              <th>Mannschaft</th>
              <th>Tore</th>
              <th>Punkte</th>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each-group select="spiel/mannschaft" group-by="@kürzel">
              <xsl:sort select="sum(current-group()/@punkte)" order="descending"/>
              <xsl:sort select="sum(current-group()/@tore)" order="ascending"/>
              <tr>
                <td><xsl:value-of select="position()"/></td>
                <td><xsl:value-of select="@kürzel"/></td>
                <td><xsl:value-of select="sum(current-group()/@tore)"/></td>
                <td><xsl:value-of select="sum(current-group()/@punkte)"/></td>
              </tr>
            </xsl:for-each-group>
          </tbody>
        </table>
      </xsl:template>
    
    </xsl:stylesheet>
    Bei der Eingabe
    Code:
    <turnier>
      <gruppe ordnung="1">
        <spiel nr="1">
          <mannschaft kürzel="a" tore="2" punkte="3"/>
          <mannschaft kürzel="b" tore="1" punkte="0"/>
        </spiel>
        <spiel nr="2">
          <mannschaft kürzel="a" tore="1" punkte="1"/>
          <mannschaft kürzel="c" tore="1" punkte="1"/>
        </spiel>
        <spiel nr="3">
          <mannschaft kürzel="b" tore="1" punkte="1"/>
          <mannschaft kürzel="c" tore="1" punkte="1"/>
        </spiel>
      </gruppe>
    </turnier>
    ist das Resultat (mit Saxon 9, http://saxon.sourceforge.net/):
    Code:
    <html lang="de">
       <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          <title>Tabellen</title>
       </head>
       <body>
          <h1>Tabellen</h1>
          
          <h2>Tabelle Gruppe 1</h2>
    
          <table>
             <thead>
                <tr>
                   <th>Position</th>
                   <th>Mannschaft</th>
                   <th>Tore</th>
                   <th>Punkte</th>
    
                </tr>
             </thead>
             <tbody>
                <tr>
                   <td>1</td>
                   <td>a</td>
                   <td>3</td>
    
                   <td>4</td>
                </tr>
                <tr>
                   <td>2</td>
                   <td>c</td>
                   <td>2</td>
                   <td>2</td>
    
                </tr>
                <tr>
                   <td>3</td>
                   <td>b</td>
                   <td>2</td>
                   <td>1</td>
                </tr>
    
             </tbody>
          </table>
          
       </body>
    </html>

    Comment


    • #3
      Sehr geehrter Herr Honnen,
      vielen Dank für Ihre Hilfe!

      Ich bin nun über ein weiteres Problem gestolpert, was die Sortierung der Tabelle anbetrifft.

      Code:
                      
      <xsl:sort select="sum(current-group()/@punkte)" order="descending"/>
      <xsl:sort select="sum(current-group()/@tore)" order="ascending"/>
      Ich würde natürlich gerne das Torverhältnis als Sortierungsgrundlage mit einbeziehen. Nur dafür sehe ich bisher keine andere Möglichkeit, als in meiner xml-datei ein weiteres Argument für die Gegentore einzufügen.

      Code:
                  <spiel nr="1">
                      <mannschaft kürzel="a" tore="4" gegentore="1" punkte="1"/>
                      <mannschaft kürzel="b" tore="1" gegentore="4" punkte="1"/>
                  </spiel>
      Das kommt mir aber äußerst ungeschickt vor. Gibt es eine Möglichkeit innerhalb eines <spiel>-tags die Tore des jeweils anderen <mannschaft>-tags auszulesen? So dass ich in der xslt-datei das Torverhältnis für alle Spiele berechnen und nach diesem sortieren kann?

      Vielen Dank

      Comment


      • #4
        Hier eine Adaption des ersten Beispieles, die die Summierung von Punkten, Toren und Gegentoren in einer Variablen speichert und dann anschliessend sortiert:
        Code:
        <xsl:stylesheet
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          exclude-result-prefixes="xs"
          version="2.0">
          
          <xsl:output method="html" indent="yes"/>
          
          <xsl:key name="k1" match="mannschaft" use="@kürzel"/>
          
          <xsl:template match="/">
            <html lang="de">
              <head>
                <title>Tabellen</title>
              </head>
              <body>
                <h1>Tabellen</h1>
                <xsl:apply-templates/>
              </body>
            </html>
          </xsl:template>
          
          <xsl:template match="gruppe">
            <h2>Tabelle Gruppe <xsl:value-of select="@ordnung"/></h2>
            <xsl:variable name="tabelle">
              <xsl:for-each-group select="spiel" group-by="mannschaft/@kürzel">
                <xsl:variable name="m"
                  select="for $s in current-group() return key('k1', current-grouping-key(), $s)"/>
                <xsl:variable name="om"
                  select="current-group()/mannschaft except $m"/>
                <mannschaft kürzel="{current-grouping-key()}"
                            punkte="{sum($m/@punkte)}"
                            tore="{sum($m/@tore)}"
                            gegentore="{sum($om/@tore)}"/>
              </xsl:for-each-group>
            </xsl:variable>
            <table>
              <thead>
                <tr>
                  <th>Position</th>
                  <th>Mannschaft</th>
                  <th>Tore</th>
                  <th>Torverhältnis</th>
                  <th>Punkte</th>
                </tr>
              </thead>
              <tbody>
                <xsl:for-each select="$tabelle/mannschaft">
                  <xsl:sort select="xs:integer(@punkte)" order="descending"/>
                  <xsl:sort select="@tore div @gegentore" order="descending"/>
                  <tr>
                    <td><xsl:value-of select="position()"/></td>
                    <td><xsl:value-of select="@kürzel"/></td>
                    <td><xsl:value-of select="@tore"/></td>
                    <td><xsl:value-of select="concat(@tore, ' : ', @gegentore)"/></td>
                    <td><xsl:value-of select="@punkte"/></td>
                  </tr>
                </xsl:for-each>
              </tbody>
            </table>
          </xsl:template>
        
        </xsl:stylesheet>
        Dabei kommt dann mit der Beispieleingabe folgendes heraus:
        Code:
        <html lang="de">
           <head>
              <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
              <title>Tabellen</title>
           </head>
           <body>
              <h1>Tabellen</h1>
              
              <h2>Tabelle Gruppe 1</h2>
        
              <table>
                 <thead>
                    <tr>
                       <th>Position</th>
                       <th>Mannschaft</th>
                       <th>Tore</th>
                       <th>Torverhältnis</th>
        
                       <th>Punkte</th>
                    </tr>
                 </thead>
                 <tbody>
                    <tr>
                       <td>1</td>
                       <td>a</td>
        
                       <td>3</td>
                       <td>3 : 2</td>
                       <td>4</td>
                    </tr>
                    <tr>
                       <td>2</td>
                       <td>c</td>
        
                       <td>2</td>
                       <td>2 : 2</td>
                       <td>2</td>
                    </tr>
                    <tr>
                       <td>3</td>
                       <td>b</td>
        
                       <td>2</td>
                       <td>2 : 3</td>
                       <td>1</td>
                    </tr>
                 </tbody>
              </table>
              
           </body>
        
        </html>

        Comment


        • #5
          Erneuten Dank an Sie Herr Honnen,
          auch wenn ich das Problem diesmal anders gelöst habe:

          Code:
                          
          <xsl:sort select="sum(current-group()/@punkte)" order="descending"/>
          <xsl:sort select="sum(current-group()/@tore) - sum(current-group()/following sibling::node()/@tore | current-group()/preceding-sibling::node()/@tore)" order="descending"/>
          <xsl:sort select="sum(current-group()/@tore)" order="descending"/>
          Mir hat sich ein neues Problem innerhalb des Projekts gestellt, was aber nichts mehr mit dem eigentlichen Threadtitel zu tun hat.

          Ich möchte neben der html-ausgabe auch eine xml-datei ausgeben, welche neue Paarungen berechnet. Der Benutzer soll nur noch die Ergebnisse eintragen müssen. Dafür suche ich eine Möglichkeit in folgendem Beispiel:
          Code:
          <spiel nr="1">
            <mannschaft kürzel="" tore="" punkte=""/>
            <mannschaft kürzel="" tore="" punkte=""/>
          </spiel>
          den Inhalt des Attributs "kürzel" an Hand von Regeln vorzubestimmen. Im Prinzip etwas wie:

          Code:
          <mannschaft kürzel="<xsl:value-of select="//achtelfinale/mannschaft[siegermannschaft]/kürzel"/>" tore="-" punkte="-"/>
          Eine Anregung dazu?

          Comment


          • #6
            Wenn man mit einem Stylesheet mehrere Ausgabedokumente erzeugen will, so geht das mit XSLT 2.0 per xsl :result-document: http://www.w3.org/TR/xslt20/#creating-result-trees
            Was das Erzeugen von Attributwerten angeht, so macht man das mit der "attribute value template"-Syntax also
            Code:
            <mannschaft kürzel="{//achtelfinale/mannschaft[siegermannschaft]/@kürzel}" punkte="-" tore="-"/>

            Comment


            • #7
              Neues und letztes Problem. Bei der ersten Transformation der gegebenen xml-datei(gruppenphase) soll der übergang zu einem ko-system vollzogen werden. Dafür trifft beispielsweise der 1. der Gruppe A auf den 2. der Gruppe B. Die Transformation dieser "Vorrunde" soll dem Nutzer eine neue xml-datei zur Verfügung stellen, wo bereits die Berechnung der neuen Paarungen vollzogen wurde.

              Mein Ansatz war mit Hilfe der Sortierung, wie ich sie schon bei den Tabellen benutzt habe den jeweils ersten bzw. zweiten auszuwählen. Das Problem ist, dass die Ausgabe nach
              Code:
              <xsl:sort .../>
              einen String ergibt, den ich nicht zu zerlegen vermag. Ich denke es ließe sich mit
              Code:
              <xsl:analze-string .../>
              etwas hinbiegen das mir den ersten und zweiten einer Gruppe ausgeben und eventuell in einer Variable speichern kann. Ich verstehe aber leider noch nicht wie ich diese Funktion benutzen kann.

              Wenn ich nach der Sortierung alleine
              Code:
               <mannschaft kürzel="{@kürzel}" tore="" punkte=""/>
              benutze bekomme ich vier neue xml-elemente. Ich hatte gehofft dass es möglich ist durch etwas wie @kürzel[1] nur ein Element ausgegen zu können, aber das scheint so nicht zu funktionieren.

              Ein weiteres Problem ist, dass sich bei 8 Paarungen gut 100 Zeilen neuer Code anhäuft, wenn ich so vorgehe, was ich äußerst unelegant finde...

              Vielen Dank!

              Comment


              • #8
                xsl: sort gibt gar nichts aus, es wird nur als Kindelement in for-each, apply-templates und for-each-group benutzt, um die Reihenfolge der Verarbeitung festzulegen.

                Ansonsten habe ich nicht wirklich verstanden, was das neuste Problem ist. Am besten mal ein Beispiel posten, dass die aktuelle Eingabe mit mehreren Gruppen enthält, und dann die dazugehörige Ausgabe, die per XSLT erzeugt werden soll.

                Comment


                • #9
                  Kurz nochmal das Ziel erklärt:
                  • Benutzer trägt Ergebnisse von Mannschaft a,b,c,d in Gruppe 1 ein und von Mannschaft e,f,g,h in Gruppe 2
                  • -a- ist 1., -b- ist 2. der Gruppe 1, -e- ist 1. und -f- ist 2. der Gruppe 2
                  • xslt datei wird ausgeführt und erstellt xml-datei in der die neuen Paarungen berechnet werden, wo -a- gegen -f- und -b- gegen -e- spielt


                  Code bis dato:
                  Code:
                  <xsl:result-document href="turnierverlauf.xml">
                      <turnierverlauf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                          xsi:noNamespaceSchemaLocation="file:/C:/.../.../turnierverlauf.xsd">
                          <xsl:copy-of select="turnierverlauf/vorrunde"/>
                          <xsl:if test="turnierverlauf/achtelfinale">
                              <xsl:copy-of select="turnierverlauf/achtelfinale"></xsl:copy-of>
                          </xsl:if>
                          <xsl:if test="turnierverlauf/viertelfinale">
                              <xsl:copy-of select="turnierverlauf/viertelfinale"></xsl:copy-of>
                          </xsl:if>
                          <xsl:if test="turnierverlauf/halbfinale">
                              <xsl:copy-of select="turnierverlauf/halbfinale"></xsl:copy-of>
                          </xsl:if>
                          <xsl:if test="turnierverlauf/platz3">
                              <xsl:copy-of select="turnierverlauf/platz3"></xsl:copy-of>
                          </xsl:if>
                          <xsl:if test="turnierverlauf/finale">
                              <xsl:copy-of select="turnierverlauf/finale"></xsl:copy-of>
                          </xsl:if>
                          <xsl:choose>
                              <xsl:when test="not(/turnierverlauf/achtelfinale)">
                                  <achtelfinale>
                                      <spiel nr="1">
                                          <xsl:for-each-group select="/turnierverlauf/vorrunde/gruppe[1]/spiel/mannschaft" group-by="@kürzel" >
                                              <xsl:sort select="sum(current-group()/@punkte)" order="descending"/>
                                              <xsl:sort select="sum(current-group()/@tore) - sum(current-group()/following-sibling::node()/@tore | current-group()/preceding-sibling::node()/@tore)" order="descending"/>
                                              <xsl:sort select="sum(current-group()/@tore)" order="descending"/>                            
                                              <mannschaft kürzel="{@kürzel}" tore="" punkte=""/>
                  <!-- an der Stelle wo jetzt nur {@kürzel} steht möchte ich eigentlich nur den ersten der Ausgabe von @kürzel haben -->
                                          </xsl:for-each-group> 
                  <!-- an dieser Stelle würde dann die Berechnung der Tabelle der zweiten Gruppe kommen und ich würde nur den 2. dieser Tabelle nehmen wollen - usw. -->
                               <spiel nr="2">[...]</spiel>
                                <spiel nr="x">[...]</spiel>
                  Ausgabe wäre dementsprechen:
                  Code:
                          <spiel nr="1">
                              <mannschaft kürzel="a" tore="" punkte=""/>
                              <mannschaft kürzel="b" tore="" punkte=""/>
                              <mannschaft kürzel="c" tore="" punkte=""/>
                              <mannschaft kürzel="d" tore="" punkte=""/>
                          </spiel>
                  heraus. Ich möchte aber das in Spiel nr1 nur der Erste dieser Gruppe angezeigt wird und eine weitere Eingabe treffen, welche den zweiten der nächsten Gruppe angibt.

                  Aber so sollte es aussehen:
                  Code:
                          <spiel nr="1">
                              <mannschaft kürzel="a" tore="" punkte=""/>
                              <mannschaft kürzel="f" tore="" punkte=""/>
                          </spiel>
                  <spiel nr="2">
                              <mannschaft kürzel="e" tore="" punkte=""/>
                              <mannschaft kürzel="b" tore="" punkte=""/>
                          </spiel>

                  Comment

                  Working...
                  X