Andreas Hippauf: XML mit XSLT in Javascript Transformieren

Hallo,

ich habe ne Webseite auf der ich XML Daten durch eine XSLT Transformation ausgeben möchte. Das ganze soll Clientseitig mittels Javascript funktionieren und tut es auch. Ich hab im Script eine Browserweiche für IE und Firefox drin, da die Ansätze ja verschieden sind. Im IE funktioniert bereits alles wie ich es mir vorstelle, nur mit Firefox hab ich noch ein Problem und ich find einfach keinen Hinweis auf die Lösung:

je nach angeklicktem Link parse ich das XSLT mit einem anderen Mode

<xsl:template match="/" mode="RPs" /> <xsl:template match="/" mode="andererMode" />

Parameterübergabe habe ich sowohl im IE als auch Firefox hingekriegt, aber den Mode kann ich für den Firefox nicht setzen, ich finde einfach keine Dokumentation in der das erwähnt wird. Kann der Firefox das noch nicht und ich muss mehrere XSLT-Dateien verwenden oder kann mir jemand bitte bitte den entsprechenden Befehl verraten? Hier mal der Ausschnitt mit der noch fehlenden Lücke im Firefox:

if (browser == "IE")  {   var processor = cache.createProcessor();   processor.input = src;

if (mode) { processor.setStartMode (mode);     }   if (variablename) { processor.addParameter (variablename, variablecontent); }

processor.transform();   result = processor.output;  }

// Firefox:  if (browser == "Firefox")  {   if (mode) { // wie lautet der Befehl im Firefox???   }   if (variablename) {xsltProcessor.setParameter(null, variablename, variablecontent);}

var fragment = xsltProcessor.transformToFragment(xmlDoc, document);     result = fragment;  }

return (result);

achja, var xsltProcessor = new XSLTProcessor();

also das Laden der XML und XSLT Datein von JS aus ist nicht mehr mein Problem, das hab ich mit Hilfe dieses Forums schon schön lösen können, mir gehts nur um das Definieren des mode-Attributs....

Ich hoffe es gibt da ne Lösung, vielen Dank schonmal im voraus

  1. Tag Andreas.

    ich habe ne Webseite auf der ich XML Daten durch eine XSLT Transformation ausgeben möchte. Das ganze soll Clientseitig mittels Javascript funktionieren und tut es auch. Ich hab im Script eine Browserweiche für IE und Firefox drin, da die Ansätze ja verschieden sind. Im IE funktioniert bereits alles wie ich es mir vorstelle, nur mit Firefox hab ich noch ein Problem und ich find einfach keinen Hinweis auf die Lösung:

    Kennst du die Mozilla XSLT Documentation?

    Siechfred

    1. Tag Andreas.

      ich habe ne Webseite auf der ich XML Daten durch eine XSLT Transformation ausgeben möchte. Das ganze soll Clientseitig mittels Javascript funktionieren und tut es auch. Ich hab im Script eine Browserweiche für IE und Firefox drin, da die Ansätze ja verschieden sind. Im IE funktioniert bereits alles wie ich es mir vorstelle, nur mit Firefox hab ich noch ein Problem und ich find einfach keinen Hinweis auf die Lösung:

      Kennst du die Mozilla XSLT Documentation?

      Siechfred

      Ja, die hab ich schon 4-5 mal und in 1-2 Sprachen gelesen, aber da steht nur wie ich Paramter setze, ich übergebe aber nicht NUR Parameter, sondern muss auch den Parse-Modus ändern....

  2. Hallo,

    also das Laden der XML und XSLT Datein von JS aus ist nicht mehr mein Problem, das hab ich mit Hilfe dieses Forums schon schön lösen können, mir gehts nur um das Definieren des mode-Attributs....

    Ich hoffe es gibt da ne Lösung, vielen Dank schonmal im voraus

    Du musst Parameter dafür übergeben: shaust du bitte hier http://forum.de.selfhtml.org/archiv/2004/4/t78019/#m451662 oder hier http://forum.de.selfhtml.org/archiv/2005/1/t97848/#m597247

    --> xsltProcessor.getParameter(null, "blablabla");

    Grüße
    Thomas

    1. Hallo,

      also das Laden der XML und XSLT Datein von JS aus ist nicht mehr mein Problem, das hab ich mit Hilfe dieses Forums schon schön lösen können, mir gehts nur um das Definieren des mode-Attributs....

      Ich hoffe es gibt da ne Lösung, vielen Dank schonmal im voraus

      Du musst Parameter dafür übergeben: shaust du bitte hier http://forum.de.selfhtml.org/archiv/2004/4/t78019/#m451662

      Das Beispiel kenn ich, damit kann ich die Parameter für XSL einstellen, aber eben NICHT den Mode.
      Parameter = $param

      mode = <xsl:template match="/" mode="Zeitschrift" />

      letzteren meinte ich

      oder hier http://forum.de.selfhtml.org/archiv/2005/1/t97848/#m597247

      --> xsltProcessor.getParameter(null, "blablabla");

      Grüße
      Thomas

      Dasselbe in grün... nochmal: Parameter ist mir klar, verwende ich bereits dank (genau dieser) Beispiele erfolgreich. Aber das ändern des mode-attributs ist mir bis jetzt nur unter dem IE gelungen, das Gegenstück in Firefox fehlt mir noch und suche ich verzweifelt.

      Bin ich da wirklich der einzige, der an sowas knobelt?

      Schnief, ich bin soooo allein und verzweifelt!

      1. Hallo,

        Du musst Parameter dafür übergeben: shaust du bitte hier http://forum.de.selfhtml.org/archiv/2004/4/t78019/#m451662

        Das Beispiel kenn ich, damit kann ich die Parameter für XSL einstellen, aber eben NICHT den Mode.
        Parameter = $param

        mode = <xsl:template match="/" mode="Zeitschrift" />

        letzteren meinte ich

        Du willst für den Dokumentkonten (d.h. für das gesamte Dokument) ein Template mit 'mode' definieren??? Und wie willst du dann das Aufrufen: in welchem Template willst du ein <xsl:apply-templates select="/" mode="Zeitschrift" /> denn verwednen?

        <xsl:param name="mode"  />

        <xsl:template match="/">
         xsl:choose
          <xsl:when test="$mode = 'Zeitschrift'">
           <xsl:apply-templates select="wurzelelement" mode="Zeitschrift" />
          </xsl:when>
          xsl:otherwise
           <xsl:apply-templates select="wurzelelement" mode="Zeitgeist" />
          </xsl:otherwise>
         </xsl:choose>
        </xsl:template>

        Grüße
        Thomas

        1. Hallo,

          Du musst Parameter dafür übergeben: shaust du bitte hier http://forum.de.selfhtml.org/archiv/2004/4/t78019/#m451662

          Das Beispiel kenn ich, damit kann ich die Parameter für XSL einstellen, aber eben NICHT den Mode.
          Parameter = $param

          mode = <xsl:template match="/" mode="Zeitschrift" />

          letzteren meinte ich

          Du willst für den Dokumentkonten (d.h. für das gesamte Dokument) ein Template mit 'mode' definieren??? Und wie willst du dann das Aufrufen: in welchem Template willst du ein <xsl:apply-templates select="/" mode="Zeitschrift" /> denn verwednen?

          Gar nicht vom XSLT, das ist so gedacht, das es vom Parser gesetzt wird, Saxon, oder wie in meinem Fall eben, Javascript.

          Also von "Aussen" quasi, damit man nur ein XSLT für verschiedene Umgebungen anwenden muss, quasi.

          Aus O Reilly XSLT, Dt. Ausgabe:

          xsl:template

          match (...)
          name (...)
          mode
           Ein Attribut, das für diese Vorlage einen Modus definiert. Ein Modus ist eine komfortable Syntax, die es Ihnen ermöglicht, für besondere Zwecke spezielle Vorlagen zu schreiben. Beispielsweise könnte man ein xsl:template mit mode="toc" schreiben, um einen Knoten für das Inhaltsverzeichnis eines Dokuments zu verarbeiten, und andere xsl:template-Elemente mit mode="print", mode="online", mode="index" usw. um die gleichen Informationen für andere Zwecke zu verarbeiten.

          1. Hallo,

            Du willst für den Dokumentkonten (d.h. für das gesamte Dokument) ein Template mit 'mode' definieren??? Und wie willst du dann das Aufrufen: in welchem Template willst du ein <xsl:apply-templates select="/" mode="Zeitschrift" /> denn verwednen?

            Gar nicht vom XSLT, das ist so gedacht, das es vom Parser gesetzt wird, Saxon, oder wie in meinem Fall eben, Javascript.

            Also von "Aussen" quasi, damit man nur ein XSLT für verschiedene Umgebungen anwenden muss, quasi.

            Aus O Reilly XSLT, Dt. Ausgabe:

            [...]

            Das ist alles korrekt, aber du kannst nicht für <template match="/"> ein mode schreiben (bzw. können schon, aber nützen wird dir das nichts), weil du dieses Template mit einer mode dann nicht aufrufen kannst. Denn dazu wäre ein apply-templates notwendig und du kannst nicht ein
            <xsl:template match="/" mode="root">
             <xsl:apply-templates select="/" mode="root" />
            </xsl:template>
            schreiben (wäre nämlich recursiv).

            Du kannst höchstes sowas schreiben:
            <xsl:template match="/">
             xsl:choose
              <xsl:when test="$format = 'pdf'">
               <xsl:apply-templates select="wurzelelement" mode="pdf" />
              </xsl:when>
              xsl:otherwise
               <xsl:apply-templates select="wurzelelement" mode="html" />
              </xsl:otherwise>
             </xsl:choose>
            </xsl:template>

            Grüße
            Thomas

            1. Aus O Reilly XSLT, Dt. Ausgabe:

              [...]

              Das ist alles korrekt, aber du kannst nicht für <template match="/"> ein mode schreiben (bzw. können schon, aber nützen wird dir das nichts), weil du dieses Template mit einer mode dann nicht aufrufen kannst. Denn dazu wäre ein apply-templates notwendig und du kannst nicht ein
              <xsl:template match="/" mode="root">
              <xsl:apply-templates select="/" mode="root" />
              </xsl:template>
              schreiben (wäre nämlich recursiv).

              Du kannst höchstes sowas schreiben:
              <xsl:template match="/">
              xsl:choose
                <xsl:when test="$format = 'pdf'">
                 <xsl:apply-templates select="wurzelelement" mode="pdf" />
                </xsl:when>
                xsl:otherwise
                 <xsl:apply-templates select="wurzelelement" mode="html" />
                </xsl:otherwise>
              </xsl:choose>
              </xsl:template>

              Grüße
              Thomas

              Nochmal: es geht NICHT um den Aufruf von Innerhalb des XSLT, sondern von aussen, den Mode bekommt der Parser schon voreingestellt.

  3. Hallo,

    ich habe ne Webseite auf der ich XML Daten durch eine XSLT Transformation ausgeben möchte. Das ganze soll Clientseitig mittels Javascript funktionieren und tut es auch. Ich hab im Script eine Browserweiche für IE und Firefox drin, da die Ansätze ja verschieden sind. Im IE funktioniert bereits alles wie ich es mir vorstelle, nur mit Firefox hab ich noch ein Problem und ich find einfach keinen Hinweis auf die Lösung:

    je nach angeklicktem Link parse ich das XSLT mit einem anderen Mode

    <xsl:template match="/" mode="RPs" />
    <xsl:template match="/" mode="andererMode" />

    Parameterübergabe habe ich sowohl im IE als auch Firefox hingekriegt, aber den Mode kann ich für den Firefox nicht setzen, ich finde einfach keine Dokumentation in der das erwähnt wird. Kann der Firefox das noch nicht und ich muss mehrere XSLT-Dateien verwenden oder kann mir jemand bitte bitte den entsprechenden Befehl verraten? Hier mal der Ausschnitt mit der noch fehlenden Lücke im Firefox:

    if (browser == "IE")
    {
      var processor = cache.createProcessor();
      processor.input = src;

    if (mode) { processor.setStartMode (mode);
        }
      if (variablename) { processor.addParameter (variablename, variablecontent); }

    processor.transform();
      result = processor.output;
    }

    // Firefox:
    if (browser == "Firefox")
    {
      if (mode) {
    // wie lautet der Befehl im Firefox???
      }
      if (variablename) {xsltProcessor.setParameter(null, variablename, variablecontent);}

    var fragment = xsltProcessor.transformToFragment(xmlDoc, document);
        result = fragment;
    }

    return (result);

    achja, var xsltProcessor = new XSLTProcessor();

    also das Laden der XML und XSLT Datein von JS aus ist nicht mehr mein Problem, das hab ich mit Hilfe dieses Forums schon schön lösen können, mir gehts nur um das Definieren des mode-Attributs....

    Ich hoffe es gibt da ne Lösung, vielen Dank schonmal im voraus

    Nachtrag:

    die Frage bleibt, aber mein Problem hat sich erledigt, ich habe das XSLT so umgeschrieben, das es nur noch ein Root-Element ohne mode verwendet, in dem die einzelnen modes mittels xsl:if Blöcken unterschieden werden. Der Mode wird dann anstatt echter mode mittels Param/Variable an den xsltProcessor übergeben....
    Nicht schön, aber führt zumindest zum Ziel.

    Das Ergebnis kann man auf meiner unten angegeben Url im linken Menue-Bereich bewundern.... Derzeit nur technisch, hübsches CSS-Design steht dann als nächstes auf dem Programm :)

    Trotzdem Danke an alle, die sich mit mir den Kopf zerbrochen haben!

    Wenn jemand noch ne Lösung für den ersten Ansatz findet, daran bin ich natürlich immer noch interessiert, man ist schließlich nicht immer in der glücklichen Lage Einfluss auf das XSLT nehmen zu können.

    1. Hallo,

      Nachtrag:

      die Frage bleibt,

      Nein, die Frage habe ich dir beantwortet: du kannst das mode-Attribut eines Templates nicht direkt als Paramter einem Apply-Templates übergeben, weder im IE noch sonstwo, schlicht weil der Wert des mode-Attributes ein sogenannter QName (Qualifizierter XML-Name) sein muss d.h. es werden keine Variblen etc. aktzptiert.

      »»aber mein Problem hat sich erledigt, ich habe das XSLT so umgeschrieben, das es nur noch ein Root-Element ohne mode verwendet, in dem die einzelnen modes mittels xsl:if Blöcken unterschieden werden. Der Mode wird dann anstatt echter mode mittels Param/Variable an den xsltProcessor übergeben....

      Nicht schön, aber führt zumindest zum Ziel.

      Das ist nicht "erldigt" sondern die einzige Lösung deines Problems.
      Wobei man einiges noch an deinem XML vereinfachen könnte und ein choose-when-otherwise wäre statt den ifs besser geignet.

      Wenn jemand noch ne Lösung für den ersten Ansatz findet, daran bin ich natürlich immer noch interessiert, man ist schließlich nicht immer in der glücklichen Lage Einfluss auf das XSLT nehmen zu können.

      Du hast diese Lösung bekommen. Eine andere gibt es nicht.

      Grüße
      Thomas

      1. Nein, die Frage habe ich dir beantwortet: du kannst das mode-Attribut eines Templates nicht direkt als Paramter einem Apply-Templates übergeben, weder im IE noch sonstwo, schlicht weil der Wert des mode-Attributes ein sogenannter QName (Qualifizierter XML-Name) sein muss d.h. es werden keine Variblen etc. aktzptiert.

        Scheinbar hab ich mein Problem unklar beschrieben: nicht im XSLT-Skript will ich das mode-Attribut an ein Template "übergeben", sondern ich will Templates je nach Modus anwenden. Das sollte mit XSLT gehen, zumindest laut W3C.

        Für den IE kann man das auch mittels Javascript direkt ansteuern, da ich im Firefox nichts entsprechendes gefunden habe, hab ich das XSLT-Script umgebaut, so dass es nun kein mode mehr verwendet, sondern ein weiteres Attribut über Javascript bekommt.

        if (browser == "IE")
         {
          var processor = cache.createProcessor();
          processor.input = src;

        // default mode Transformation

        if (mode) {
             // processor.setStartMode (mode);
            processor.addParameter ("mode", mode);
            }
          if (variablename) { processor.addParameter (variablename, variablecontent); }

        processor.transform();
          result = processor.output;
         }

        Das auskommentierte da oben processor.setStartMode (mode) funktioniert wirklich im IE, ruhig mal ausprobieren! Nur im Firefox ist das entweder vergessen worden, oder bewußt nicht gemacht worden, ich weiß es nicht. Wenn man nicht den Quelltext lesen will findet man die entsprechende Info im Netz sehr schlecht, zumindest ich...

        »»aber mein Problem hat sich erledigt, ich habe das XSLT so umgeschrieben, das es nur noch ein Root-Element ohne mode verwendet, in dem die einzelnen modes mittels xsl:if Blöcken unterschieden werden. Der Mode wird dann anstatt echter mode mittels Param/Variable an den xsltProcessor übergeben....

        Nicht schön, aber führt zumindest zum Ziel.

        Das ist nicht "erldigt" sondern die einzige Lösung deines Problems.

        Nein, im IE ging es wie oben geschrieben mit dem Mode wunderbar.

        Wobei man einiges noch an deinem XML vereinfachen könnte und ein choose-when-otherwise wäre statt den ifs besser geignet.

        Stimmt, bau ich mal um, spätestens wenn ich ne Idee hab, ob und wie man das im Opera macht, wirds mit ifthen eh unhandlich.

        Wenn jemand noch ne Lösung für den ersten Ansatz findet, daran bin ich natürlich immer noch interessiert, man ist schließlich nicht immer in der glücklichen Lage Einfluss auf das XSLT nehmen zu können.

        Du hast diese Lösung bekommen. Eine andere gibt es nicht.

        Stimmt nur für den Firefox ;)

        1. Hallo,

          Nein, die Frage habe ich dir beantwortet: du kannst das mode-Attribut eines Templates nicht direkt als Paramter einem Apply-Templates übergeben, weder im IE noch sonstwo, schlicht weil der Wert des mode-Attributes ein sogenannter QName (Qualifizierter XML-Name) sein muss d.h. es werden keine Variblen etc. aktzptiert.

          Scheinbar hab ich mein Problem unklar beschrieben: nicht im XSLT-Skript will ich das mode-Attribut an ein Template "übergeben", sondern ich will Templates je nach Modus anwenden. Das sollte mit XSLT gehen, zumindest laut W3C.

          Wie gesagt, das geht auch, aber:

          Für den IE kann man das auch mittels Javascript direkt ansteuern, da ich im Firefox nichts entsprechendes gefunden habe,

          Was MS macht (setStartMode) ist zwar wirklich interessant, aber eben eine hauseigene Erweiterung des MXSMLs.

          Was du nämlich möchtest ist:
          <xsl:param name="mode" />
          ...
          <xsl:apply-templates select="autos" mode="{$mode}" />

          Und das geht nicht im XSLT. Wenn du das so verstanden hast, hast du etwas in der W3C-Specifikation falsch interpretiert.

          Die behaptung von MS:
          ------------------------
          Using setStartMode is essentially the same as an XSLT style sheet that starts with the following rule.

          <xsl:template match="/">
             <xsl:apply-templates select="*" mode="{mode}"/>
          </xsl:template>
          ------------------------
          bezieht sich ja auch nur auf den JavaScript aufruf.

          Das ist nicht "erldigt" sondern die einzige Lösung deines Problems.

          Nein, im IE ging es wie oben geschrieben mit dem Mode wunderbar.

          Versuche mal im IE das so zu machen (das du den Parameter mode normal mit addParameter übergibst):
          <xsl:param name="mode" />
          ...
          <xsl:apply-templates select="autos" mode="{$mode}" />

          Er wird das auch ankreiden:
          "Dieser Name darf nicht das Zeichen '{' enthalten: -->{<--$mode}"

          Wie gesagt, die Möglichkeit mit JavaScript dies vorzutäuschen ist eine proprietäre Erweiterung, die nichts mit XSLT zu tun hat.

          Natürlich sehe ich ein, dass das für dich ärgerlich ist, aber anderes als beschrieben kannst du es nicht machen.

          Grüße
          Thomas

          1. Natürlich sehe ich ein, dass das für dich ärgerlich ist, aber anderes als beschrieben kannst du es nicht machen.

            Ok, wieder was gelernt, danke! Deswegen find ich da nirgends was für den Firefox. Also paßt meine Lösung im Prinzipt ja schon, muss ich nur noch das häßliche if then gegen choose tauschen.

            Nen Tip, ob sich das auch oder eben nicht, im Opera realisieren läßt, hast nicht zufällig, oder? Oder wenigstens ne gute Einstiegs-Url, wo man da mit Lesen anfangen könnte :)

            1. Hallo,

              Nen Tip, ob sich das auch oder eben nicht, im Opera realisieren läßt, hast nicht zufällig, oder? Oder wenigstens ne gute Einstiegs-Url, wo man da mit Lesen anfangen könnte :)

              XSLT Unterstützung gibt es bei Opera erst ab 9 (Opera 9.0 Preview 1 ist aktuell)
              http://my.opera.com/community/forums/topic.dml?id=108345
              http://snapshot.opera.com/windows/w90p1.html

              Die XSLT Ünterstüzung in P1 ist aber noch fehlerhaft.

              Ansonsten geht es in Opera (oder sollte das) wie im Gecko
              http://my.opera.com/community/forums/topic.dml?id=110075

              Grüße
              Thomas