Erik: XML Daten filtern mit Auswahlliste

Moin Moin,

ich bastel an einer Filmdatenbank in XML. In der <filmliste> hat jeder <film> die Tags <name> und <genre>. Jetzt möchte ich meine Ausgabe nach Genre filtern können. Dabei sollen die verschiedenen Genres nicht in der Auswahlliste fest vorgegeben, sondern aus den XML Daten herausgezogen werden. Bis jetzt sieht mein Entwurf so aus:

<select name="meineauswahl" size="1">
  <xsl:for-each select="filmliste/film/genre">
    <option><xsl:value-of select="." />
    </option>
  </xsl:for-each>
</select>

<xsl:for-each select="filmliste/film">
  <xsl:value-of select="name" /><br>
</xsl:for-each>

Wie kann ich dafür sorgen, dass jedes Genre nur einmal in der Auswahlliste erscheint. Und wie filter ich anschliessend nach dem ausgewählten Element.

Danke!... Erik

  1. echo $begrüßung;

    ich bastel an einer Filmdatenbank in XML. In der <filmliste> hat jeder <film> die Tags <name> und <genre>. Jetzt möchte ich meine Ausgabe nach Genre filtern können. Dabei sollen die verschiedenen Genres nicht in der Auswahlliste fest vorgegeben, sondern aus den XML Daten herausgezogen werden.

    Das, würde ich sagen, geht wegen des schlechtes "Datenbank"-Designs nicht. Mit SQL könnte man mit SELECT DISTINCT genre ... alle Genre ohne Dopplungen erhalten. Für XSLT/XPath habe ich keine entsprechende Funktion oder Lösung gefunden.

    Wie kann ich dafür sorgen, dass jedes Genre nur einmal in der Auswahlliste erscheint. Und wie filter ich anschliessend nach dem ausgewählten Element.

    Ich würde für Genre eine extra Struktur aufbauen und in den Filmdaten darauf verweisen (so wie man das in einer DB machen würde).

    <genres>
      <genre id="1">genre1</genre>
      <genre id="2">genre2</genre>
    </genres>

    <filme>
      <film>
       <genre>1</genre>
       <name>film1</name>
      </film>
      <film>
       <genre>2</genre>
       <name>film2</name>
      </film>
    </filme>

    Damit gibt es kein Problem mehr mit den Select-Listen. Doch wie kommt der Genre-Name anstatt der ID in eine Auflistung der Filme? Mit einem xsl:key.

    <xsl:key name="genre" match="genres/genre" use="@id" />
    Der wird einmalig definiert und dann kann wie folgt auf den Genre-Namen zugegriffen werden:

    <xsl:for-each select="filme/film">
      Name: <xsl:value-of select="name" /><br />
      Genre: <xsl:value-of select="key('genre', genre)" />
    </xsl:for-each>

    echo "$verabschiedung $name";

    1. echo $begrüßung;

      echo auch,

      ich bastel an einer Filmdatenbank in XML. In der <filmliste> hat jeder <film> die Tags <name> und <genre>. Jetzt möchte ich meine Ausgabe nach Genre filtern können. Dabei sollen die verschiedenen Genres nicht in der Auswahlliste fest vorgegeben, sondern aus den XML Daten herausgezogen werden.

      Das, würde ich sagen, geht wegen des schlechtes "Datenbank"-Designs nicht.

      Ah!

      Mit SQL könnte man mit SELECT DISTINCT genre ...

      Klar kann man mit Kanonen auf Spatzen schießen.

      »»alle Genre ohne Dopplungen erhalten. Für XSLT/XPath habe ich keine entsprechende Funktion oder Lösung gefunden.

      Das heisst aber deshalb noch nicht, dass es in XSL nicht möglich ist?

      Ich würde für Genre eine extra Struktur aufbauen und in den Filmdaten darauf verweisen (so wie man das in einer DB machen würde).

      XML != DB.

      <xsl:key name="genre" match="genres/genre" use="@id" />

      Das ist schon fast richtig, siehe oben.

      Grüße
      Thomas

      --
      Surftip: kennen Sie schon Pipolino's Clowntheater?
      http://www.clowntheater-pipolino.net/
      1. echo $begrüßung;

        Mit SQL könnte man mit SELECT DISTINCT genre ...

        Klar kann man mit Kanonen auf Spatzen schießen.

        Tut mir leid, aber ich sehe hier keinen Zusammenhang zwischen dem Sprichwort und meinem Vergleich zu SQL.

        Für XSLT/XPath habe ich keine entsprechende Funktion oder Lösung gefunden.

        Das heisst aber deshalb noch nicht, dass es in XSL nicht möglich ist?

        Ja, ich schloss das mit meiner Formulierung nicht generell aus.

        Ich würde für Genre eine extra Struktur aufbauen und in den Filmdaten darauf verweisen (so wie man das in einer DB machen würde).

        XML != DB.

        Aha! Das hätte ich jetzt nicht gedacht. Und da gehört das also zum guten Ton, redundate Daten zu verwalten. Wieder was gelernt.

        echo "$verabschiedung $name";

        1. Hallo,

          echo $begrüßung;

          Ist das eigentlich Absicht bei dir, oder stimmt was in deinen Userconfig-Einstellungen nicht?

          Mit SQL könnte man mit SELECT DISTINCT genre ...

          Klar kann man mit Kanonen auf Spatzen schießen.

          Tut mir leid, aber ich sehe hier keinen Zusammenhang zwischen dem Sprichwort und meinem Vergleich zu SQL.

          Der OP hat eine simple XML-Datei und du schlägst ihm praktisch vor, er soll MySQL installieren und alles in die DB tun.

          Ich würde für Genre eine extra Struktur aufbauen und in den Filmdaten darauf verweisen (so wie man das in einer DB machen würde).

          XML != DB.

          Aha! Das hätte ich jetzt nicht gedacht. Und da gehört das also zum guten Ton, redundate Daten zu verwalten. Wieder was gelernt.

          Was redudant ist, kann man so oder so sehen.
          Ich sehe das:
          ---------------------------------
          <genres>
            <genre id="1">genre1</genre>
            <genre id="2">genre2</genre>
          </genres>

          <filme>
            <film>
             <genre>1</genre>
             <name>film1</name>
            </film>
            <film>
             <genre>2</genre>
             <name>film2</name>
            </film>
          </filme>
          ---------------------------------

          um eingies umständlicher und redudanter an, als folgendes:
          ---------------------------------
          <filme>
            <film>
             <genre>sci-fi</genre>
             <name>film1</name>
            </film>
            <film>
             <genre>horror</genre>
             <name>film2</name>
            </film>
          </filme>
          ----------------------------------

          Lernen kann man immer, z.B. dass DB-Desing wirklich nicht XML-Desing ist. ;-)

          Grüße
          Thomas

          --
          Surftip: kennen Sie schon Pipolino's Clowntheater?
          http://www.clowntheater-pipolino.net/
          1. Frieden!

            Die Idee wie bei einer DB 2 Tabellen zu basteln und zu verknüpfen werde ich vielleicht später mal aufgreifen.

            Das Konstrukt zum Filtern der doppelten Einträge ist super - auch wenns ichs nicht kapier <verneig />

            Das Übergeben des ausgewälten Listenfeldes mit einer Variable werd ich mal suchen...

            Grüße... Erik

          2. ... und Danke an euch!

            Erik

  2. Hallo,

    Wie kann ich dafür sorgen, dass jedes Genre nur einmal in der Auswahlliste erscheint.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="genre" match="genre" use="." />

    ...

    <select name="meineauswahl" size="1">
         <xsl:for-each select="filmliste/film/genre[generate-id(.) = generate-id(key('genre', .)[1])]">
          <option><xsl:value-of select="." /></option>
         </xsl:for-each>
        </select>

    Und wie filter ich anschliessend nach dem ausgewählten Element.

    Wenn du dein XMl und XSL am Server verarbeitest, übergibt einen Paramter in der URL  und dann frage du auf diesen Parameter ab:
    <xsl:param name="genre" />

    <xsl:if test="$genre != ''">
          <xsl:apply-templates select="filmliste/film[genre = $genre]" />
         </xsl:if>

    Oder wenn du die Transformation dem Browser überläßt, mit JavaScript. (Wen du im Archiv nach XSL, Javascript, Variable und nach meinem Namen suchst, findest du einige Beispiele.

    Grüße
    Thomas

    --
    Surftip: kennen Sie schon Pipolino's Clowntheater?
    http://www.clowntheater-pipolino.net/