Carsten: XSLT Zwischenspeicher?

Hallo Forum,

ich hab da ein paar grundlegende Fragen und hoffe dass die Beschreibung verständlich ist.

Eine Datei, vielleicht auch mehrere xml-Dateien mit gleicher Struktur,

<aa>
 <ww>w5</ww>
 <ww>w3</ww>
 <ww>w2</ww>
 <ww>w4</ww>
</aa>
<aa>
 <ww>wa</ww>
 <ww>wc</ww>
 <ww>wb</ww>
 <ww>w1</ww>
</aa>

Wenn dazu im Stylesheet ähnlich folgendem Schema gearbeitet wird:
<xsl:for-each select="aa">
<xsl:sort select="ww" />

erhalte ich später eine Darstellung bei der die beiden Blöcke "aa" nur intern sortiert werden.
Also w2 w3 w4 w5 w1 wa wb wc. Wie erreiche ich w1 w2 ..?

Kann ich erst in einer Art Zwischenspeicher sammeln, oder kann ich das entstandene Dokument einfach nochmal neu abfragen und überschreiben?

Grüsse,

Carsten

  1. Hallo,

    Eine Datei, vielleicht auch mehrere xml-Dateien mit gleicher Struktur,
    Wenn dazu im Stylesheet ähnlich folgendem Schema gearbeitet wird:
    <xsl:for-each select="aa">
    <xsl:sort select="ww" />

    erhalte ich später eine Darstellung bei der die beiden Blöcke "aa" nur intern sortiert werden.
    Also w2 w3 w4 w5 w1 wa wb wc.

    Das dürfte ja logisch sein, oder? Schließlich definiert du ja etwas für jede einzelne <aa> Element mit <xsl:for-each select="aa">.

    Wie erreiche ich w1 w2 ..?

    <xsl:apply-templates select="ww">
     <xsl:sort />
    </xsl:apply-templates>

    Kann ich erst in einer Art Zwischenspeicher sammeln,

    Theoretisch ja, mit xsl:key und key(), aber ich kenne weder dein XSL noch dein XML noch dein Zielformat und es könnte u.U. kompliziert bzw. gar nicht möglich werden.

    oder kann ich das entstandene Dokument einfach nochmal neu abfragen und überschreiben?

    Das muss du ja eigentlich wissen ;-)
    Ist das entandene Dokument XML? Dann kannst du es entweder auf dem Server speichern, oder versuchen es im Speicher zu halten und dann mit DOM darauf zuzugreifen und es zu bearbeiten.

    Grüße
    Thomas

    1. Hallo Thomas,

      <xsl:apply-templates select="ww">
       <xsl:sort />
      </xsl:apply-templates>

      danke, aber das macht erstmal gar keinen Unterschied, das Problem dass bei mehreren Dateien nur jedes <xsl:apply-templates select="document... für sich sortiert bleibt.

      Grüsse,

      Carsten

      1. Hallo Carsten,

        danke, aber das macht erstmal gar keinen Unterschied, das Problem dass bei mehreren Dateien nur jedes <xsl:apply-templates select="document... für sich sortiert bleibt.

        Folgendes sollte eigentlich genau das tun was du möchtest:
        <xsl:apply-templates select="document('a.xml')//aa/ww | document(b.xml)//aa/ww" />

        Grüße
        Thomas

        1. Hallo Thomas,

          Folgendes sollte eigentlich genau das tun was du möchtest:
          <xsl:apply-templates select="document('a.xml')//aa/ww | document(b.xml)//aa/ww" />

          das ist zwar eleganter, aber im Ergebnis noch ähnlich: entweder lässt sich gar nichts sortieren, oder abgeändert bei document('a.xml')| oder document('a.xml')/aa werden wieder die Dateien für sich sortiert. Müsste ich bei //aa/ww irgendwie ein übergeordnetes Element erzeugen um sortieren zu können?

          Grüsse,

          Carsten

          1. Hallo Carsten,

            das ist zwar eleganter, aber im Ergebnis noch ähnlich: entweder lässt sich gar nichts sortieren, oder abgeändert bei document('a.xml')| oder document('a.xml')/aa werden wieder die Dateien für sich sortiert. Müsste ich bei //aa/ww irgendwie ein übergeordnetes Element erzeugen um sortieren zu können?

            OK, das mit //aa war ja nur als Beispiel gemeint.
            document() liefert dir nur den Wurzelknoten der eingebundenen XML-Datei, also muss du von da an ausgehen und den notwendigen Pfad angeben:
            <root>
              <bla>
                <blabla> ...

            um auf <blabla> zugreifen zu können:
            document('root.xml')/bla/blabla

            Das | ist das 'union operator', d.h. es werden die selektierte Kontensets vermengt und die duplikate gelöscht.

            Du kannst dir die Seite unter http://www.dpawson.co.uk/xsl/sect2/N2602.html ansehen, dort geht es fast immer und die Frage wie man mehrere XML-Dateien mit einer XSL behandelt.

            Sonst wüsste ich nicht, wie ich dir noch helfen könnte.

            Grüße
            Thomas

            1. Hallo Thomas,

              um auf <blabla> zugreifen zu können:
              document('root.xml')/bla/blabla

              Das sollte doch nicht mehr das Problem sein nachdem ich | angewandt habe?

              Das | ist das 'union operator', d.h. es werden die selektierte Kontensets vermengt und die duplikate gelöscht.

              Offenbar krieg ich es nicht hin den gemischten Kontent zu sortieren, weil nach dem Mischen ein Knoten dazu fehlt oder ich den nicht kenne und das Schema 'root... ' nicht übertragen kann.

              Du kannst dir die Seite unter http://www.dpawson.co.uk/xsl/sect2/N2602.html ansehen, dort geht es fast immer und die Frage wie man mehrere XML-Dateien mit einer XSL behandelt.

              Da hatte ich schon gesucht und nichts passendes gefunden.

              Sonst wüsste ich nicht, wie ich dir noch helfen könnte.

              Du sollst ja gar nicht meine "Hausaufgaben" machen, aber vielleicht könntest dir das ja nochmal kurz anschauen ob du den oder die "Knoten" findest.

              Die eins.xml und zwei.xml würden wohl als reale Daten mehr Elementebenen haben, z.B.
               <adressen>
                          <person><name> Meyr </name>
                                  <telefon> 04711 </telefon>
                           </person>
              Ausserdem ist jetzt gerade noch ein Fehler drin der deutlich macht dass der Teil mit dem 'union operator' entweder doppelt aufgerufen wird, oder nicht richtig ausgeführt wird, mal ergibt die Anzeige
              -wa -- wc -- wb -- w1 -- w5 -- w3 -- w2 -- w4 -, dann (falls es nicht ein browsertypischer Effekt beim Reload ist)

              • w5 -- w3 -- w2 -- w4 -- wa -- wc -- wb -- w1 -

              test.xml:

              <?xml version="1.0" encoding="iso-8859-1"?>
              <?xml-stylesheet type="text/xsl" href="test.xsl"?>
               <F_F>
               </F_F>

              test.xsl:

              <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
              <xsl:template match="/F_F">
              <html><body><h1>Test</h1>
              <xsl:apply-templates select="document('zwei.xml')//A_A/W_W|document('eins.xml')//A_A/W_W"/>
              </body>
              </html>
              </xsl:template>
              <xsl:template match="W_W">
              <xsl:for-each select=".">
              <xsl:sort select="."/>
              <div>-
              <xsl:value-of select="." />
              -</div>
              </xsl:for-each>
              </xsl:template>
              </xsl:stylesheet>

              eins.xml:

              <?xml version="1.0" encoding="iso-8859-1"?>
              <A_A>
               <W_W> w5 </W_W>
               <W_W> w3 </W_W>
               <W_W> w2 </W_W>
               <W_W> w4 </W_W>
              </A_A>

              zwei.xml:

              <?xml version="1.0" encoding="iso-8859-1"?>
              <A_A>
               <W_W> wa </W_W>
               <W_W> wc </W_W>
               <W_W> wb </W_W>
               <W_W> w1 </W_W>
              </A_A>

              Grüsse + Dank,

              Carsten

              1. Hallo Carsten,

                Du sollst ja gar nicht meine "Hausaufgaben" machen, aber vielleicht könntest dir das ja nochmal kurz anschauen ob du den oder die "Knoten" findest.

                Die XML-Dateien sind unverändern (bloß umbenannt habe ich sie)
                Die XSL-Datei schaut nun so aus:
                --------------------------------------------------------------
                <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                 <xsl:template match="/F_F">
                  <html>
                   <body>
                    <h1>Test</h1>
                    <xsl:apply-templates select="document('carsten1.xml')/A_A/W_W | document('carsten2.xml')/A_A/W_W">
                     <xsl:sort select="."/>
                    </xsl:apply-templates>
                   </body>
                  </html>
                 </xsl:template>
                 <xsl:template match="W_W">
                   <div>-<xsl:value-of select="." />-</div>
                 </xsl:template>
                </xsl:stylesheet>
                --------------------------------------------------------------

                Ich erhalte eine ausgabe:
                Test

                • w1 -
                • w2 -
                • w3 -
                • w4 -
                • w5 -
                • wa -
                • wb -
                • wc -

                Was es das?

                Grüße
                Thomas

                1. Hallo Carsten,

                  eigentlich reicht auch nur <xsl:sort />

                  Grüße
                  Thomas

                  1. Hallo Thomas,

                    Was es das?

                    ja danke, das wars!

                    Und es ist so auch sehr klar und einleuchtend, allerdings überlege ich doch noch wie man sich die entstandene Struktur vorstellen kann.

                    Der 'union operator' bewahrt ja offenbar die vorhandenen Strukturen, hat jetzt nach sort jedes W_W ein eigenes übergeordnetes A_A, oder gibt es nur noch eins für alle W_W, oder ist es gerade falsch so einen linearen Ablauf oder das Ergebnis als Modell abzubilden, zumal sich das Ergebnis anscheinend später nicht so einfach nochmals umsortieren liesse?

                    Grüsse,

                    Carsten

                    1. Hallo, Carsten,

                      Und es ist so auch sehr klar und einleuchtend, allerdings überlege ich doch noch wie man sich die entstandene Struktur vorstellen kann.

                      verwende statt <apply-tamplates> <copy-of> mit dem sleben select argument (<sort> geht dabei nicht) und du hast im ergebnissdukument die struktur zum anschauen.

                      »»Der 'union operator' bewahrt ja offenbar die vorhandenen Strukturen, hat jetzt nach sort jedes W_W ein eigenes übergeordnetes A_A, oder gibt es nur noch eins für alle W_W,

                      warum probierst es nicht aus? ;-) du könntest ja im template für 'w_w' auch auf das elternelement zurückgreifen <value-of select="../a_a/@wasauchimmerattribut" />
                      du kannst, ich weiss du wirst mehrere elemente im 'a_a' haben, genau so gut einen templat für a_a erstellen und mit apply-templates dann a_a ansteueren, und sortieren kannst du dann auch nach einem unterlement: <sort select="mensch/nachname">

                      grüße
                      thomas