XSL und "Variablen"...

mcnois

Grünschnabel
Hi Folks,

habe mal wieder ein Verständnisproblem bei XSL. Vielleicht kann mir ja jemand helfen.
Ich habe ein Elternelement und viele Kindelemente. Ich durchlaufe alle Kindelemente und prüfe deren Inhalt ab. Je nach gefundenem Inhalt sollen die Elemente nun verschiedenen Gruppen zu geordnet werden. Beispiel:

Code:
<LISTE>
   <Item 1>A</Item 1>
   <Item 2>B</Item 2>
   <Item 3>A</Item 3>
   <Item 4>A</Item 4>
   <Item 5>A</Item 5>
   <Item 6>B</Item 6>
   <Item 7>B</Item 7>
   <Item 8>A</Item 8>
   ...usw
</LISTE>

Ich möchte nun also z.B. alle Kindelemente <Item x> mit dem Wert A und alle mit dem Wert B einer Gruppe zuweisen. Mein Gedanke war, eine globale Variable zu erstellen und dann je nach gefundenem Wert diesen an die entsprechende Variable anzuhängen, ungefähr so:

Code:
<xsl:variable name="A" select="'Gruppe A:'"/>
<xsl:variable name="B" select="'Gruppe B:'"/>

<xsl:template match="/">
   <xsl:if test="Item 1">
      <xsl:value-of select="concat( $A, Item1, '-' )" />
   </xsl:if>
   <xsl:if test="Item 3">
      <xsl:value-of select="concat( $A, Item3, '-' )" />
   </xsl:if>
   usw...
</xsl:template>

Das Ganze soll erst zum Schluß ausgegeben werden, und als Ergebnis soll dann erscheinen:

Code:
Gruppe A:A-A-A-A-A-
Gruppe B:B-B-B-

Allerdings funktioniert das so nicht, da Variablen in XSL ja nicht wirklich variabel sind. :(
Weiß jemand eine Möglichkeit, wie man so etwas realisieren kann?
Wahrscheinlich stelle ich mich wie immer bloß zu dämlich an, aber ich krieg's einfach nicht gebacken.

Gruß mcnois
 
Hi.

Da mußt du schon Templates verwenden. Damit kannst du die Elemente dann rekursiv mit call-template verarbeiten.

Gruß
 
Hi,

danke für Deine Antwort. Ich ahnte sowas schon, allerdings sind Ahnen und WIssen zwei verschiedene Dinge.
Ich hab das also mit Templates versucht. Hier mal einer von mehreren unterschiedlichen Versuchen:

Code:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="ParamA" select="'A'" />

<xsl:template match="/">
   <xsl:call-template name="T1">
      <xsl:with-param name="ParamA" />
   </xsl:call-template>
</xsl:template>

<xsl:template name="T1" match="ELEMENT">
   <xsl:value-of select="concat( $ParamA, KIND1 )" />   
   <xsl:call-template name="T2">
      <xsl:with-param name="ParamA" />
   </xsl:call-template>
</xsl:template>

<xsl:template name="T2" match="ELEMENT">
   <xsl:value-of select="concat( $ParamA, KIND2 )" />   
   <xsl:call-template name="T3">
      <xsl:with-param name="ParamA" />
   </xsl:call-template>
</xsl:template>

<xsl:template name="T3" match="ELEMENT">
   <xsl:value-of select="concat( $ParamA, KIND3 )" />   
</xsl:template>

</xsl:stylesheet>

Egal, ob die Templates kaskadierend oder sequentiell aufgerufen werden, wie ich es auch drehe, das Ergebnis ist nicht das gewünschte. Eigentlich auch logisch, wenn sich Variablen eher wie Konstanten verhalten.
Ich habe mit Sicherheit irgendwo einen Denkfehler, ich komm bloß nicht drauf, wo.
Mein erstes Beispiel in diesem Thread war sicher auch nicht aussagekräftig genug.
Mir geht es darum, innerhalb eines Elternelements die komplett unterschiedlich bezeichneten Kindelemente auszuwerten, diese Informationen speziell gruppiert zu sammeln und erst ganz am Ende auszugeben. Sobald ich aber xsl:value-of select="..." benutze, erfolgt eine Ausgabe, die an dieser Stelle nicht gewünscht ist.
Inzwischen frage ich mich, ob das überhaupt so möglich ist, wie ich mir das vorstelle...? :confused:
Wenn aber der o.a. Weg in die richtige Richtung führen sollte, wo steckt dann er Fehler? :(

Grüße
 
Hi.

Du müßtest deine Resultate in den Parametern aggregieren, also in xsl:with-param den alten Wert des Parameters mit dem neuen konkatenieren wenn du call-template aufrufst.

Gruß

PS: Weißt du denn wieviele Gruppen es gibt? Eigentlich könntest du auch foreach verwenden.
 
Hi,

es werden im Moment an die 150 Gruppen sein. Da das aber noch nicht genau feststeht, möchte ich die Templates möglichst so erstellen, daß ich sie jederzeit leicht neu erstellen bzw. ändern oder erweitern kann.
Auf jeden Fall erst mal Danke für Deine schnelle Hilfe. Ich werd jetzt noch mal über das Ganze drüber schauen und es mit concat machen, ich hoffe, das ich das hinkriege.

Zum besseren Verständnis häng ich nochmal einen Auszug der echten Daten an, mit denen ich das Ganze zu tun gedenke.

Code:
<?xml version="1.0"?>
<OMeS>
  <PMSetup>
    <PMMOResult>
      <PMTarget>
        <M1011C0>0</M1011C0>
        <M1011C1>1</M1011C1>
        <M1011C10>10</M1011C10>
        <M1011C11>11</M1011C11>
        <M1011C12>12</M1011C12>
        <M1011C13>13</M1011C13>
        <M1011C14>14</M1011C14>
        <M1011C15>15</M1011C15>
        <M1011C16>16</M1011C16>
        <M1011C17>17</M1011C17>
        <M1011C18>18</M1011C18>
        <M1011C19>19</M1011C19>
        <M1011C2>2</M1011C2>
        <M1011C20>20</M1011C20>
               .
               .
               .
        <M1011C57>57</M1011C57>
        <M1011C58>58</M1011C58>
        <M1011C59>59</M1011C59>
        <M1011C6>6</M1011C6>
        <M1011C60>0</M1011C60>
        <M1011C61>61</M1011C61>
        <M1011C62>62</M1011C62>
        <M1011C63>63</M1011C63>
        <M1011C64>64</M1011C64>
        <M1011C65>0</M1011C65>
        <M1011C66>0</M1011C66>
        <M1011C67>67</M1011C67>
        <M1011C68>68</M1011C68>
        <M1011C69>69</M1011C69>
        <M1011C7>7</M1011C7>
        <M1011C70>70</M1011C70>
        <M1011C71>71</M1011C71>
        <M1011C8>8</M1011C8>
        <M1011C9>9</M1011C9>
      </PMTarget>
    </PMMOResult>
  </PMSetup>
</OMeS>

Ich muß also innerhalb PMTarget alle Elemente auswerten. Diese Elemente bekommen dann einen sprechenden Namen und gehören zu unterschiedlichen Gruppen. Zu welcher Gruppe, das erfahre ich quasi erst, wenn ich den sprechenden Namen zugewiesen habe. Also z.B. würden die Elemente M1011C0 und M1011C12 zu einer Gruppe gehören, andere Elemente zu einer anderen usw. Das ganze wiederholt sich dann im nächsten PMTarget erneut.

Die Idee war nun, durch diese Gruppierung eine Vorsortierung vorzunehmen, indem ich alle zur gleichen Gruppe gehörenden Ms hintereinander hänge und sie am Schluß Gruppe für Gruppe ausgebe. Da aber alle M-Elemente anders heißen, wird das mit der for-each-Schleife sicher nichts werden.

Ich vermute stark, ich hab ein grundsätzliches Verständnisproblem mit XSL. Kennst Du vielleicht ein gutes Tutorial, daß relativ verständlich etwas über die Arbeitsweise des XSL-Interpreters verrät?

Herzlichen Dank für Deine Hilfe

Grüße
 
Zurück