Announcement

Collapse
No announcement yet.

Standard Problem Schleife

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

  • Standard Problem Schleife

    Hi, ich verzweifel hier an einer (wie ich zuerst dachte) ziemlich simplen Aufgabe.

    Ich möchte aus einer XML-Datei eine HTML Datei bauen - so weit so gut. Nun bin ich an eine Stelle geraten, an der ich einfach nicht weiter komme. Ich habe nun den ganzen Tag gegoogelt, Foren und Mailinglisten gelesen aber totzdem komme ich nicht weiter.

    Folgende XML habe ich (nur der betreffende Abschnitt):
    Code:
    <files>
      <file firstPart="6" lastPart="6" title="Test 6">
        <fUrl>http://localhost/test_6.doc</fileURL>
        <fileDesc part="6">Teil 6 - In diesem Teil behandele ich ...</fileDesc>
      </file>
      <file firstPart="7" lastPart="9" title="Test 7 / Test 8 / Test 9">
        <fUrl>http://localhost/test_7_8_9.doc</fileURL>
        <fileDesc part="7">Teil 7 - Hier geht es um ...</fileDesc>
        <fileDesc part="8">Teil 8 - Dieses Kapitel handelt von ...</fileDesc>
        <fileDesc part="9">Teil 9 - Im 9. Kapitel ...</fileDesc>
      </file>
      <file firstPart="12" lastPart="12" title="Test 12">
        <fUrl>http://localhost/test_12.doc</fileURL>
        <fileDesc part="12">Teil 12 - In diesem Teil behandele ich ...</fileDesc>
      </file>
      ...
      <file firstPart="500" lastPart="502" title="Test 500 / Test 501 / Test 502">
        <fUrl>http://localhost/test_500_502.doc</fileURL>
        <fileDesc part="500">Teil 500 - Hier geht es um ...</fileDesc>
        <fileDesc part="501">Teil 501 - Dieses Kapitel handelt von ...</fileDesc>
        <fileDesc part="502">Teil 502 - Diesmal beginne ich ...</fileDesc>
      </file>
      ...
    <files>
    Daraus möchte ich folgendes machen:
    Code:
    <div>
      <a id="a_6" href="http://localhost/test_6.doc">Test 6</a><br>
      <span>Teil 6 - In diesem Teil behandele ich ...</span>
    </div>
    
    <div>
      <a id="a_7" href="http://localhost/test_7_8_9.doc">Test 7</a><br>
      <span>Teil 7 - Hier geht es um ...</span>
    </div>
    
    <div>
      <a id="a_8" href="http://localhost/test_7_8_9.doc">Test 8</a><br>
      <span>Teil 8 - Dieses Kapitel handelt von ...</span>
    </div>
    
    <div>
      <a id="a_9" href="http://localhost/test_7_8_9.doc">Test 9</a><br>
      <span>Teil 9 - Im 9. Kapitel ...</span>
    </div>
    
    <div>
      <a id="a_12" href="http://localhost/test_12.doc">Test 12</a><br>
      <span>Teil 12 - In diesem Teil behandele ich ...</span>
    </div>
    ...
    Wie gesagt, auf den ersten Blick sehr einfach. Allerdings möchte ich genau 20 Einträge (entweder die ersten 20 oder die letzten 20) auf einer Seite haben.

    Mein erster Ansatz war folgender:
    Code:
    <xsl:for-each select="files/file[position() &lt; 21]">
      <xsl:sort select="position()" data-type="number" order="descending"/>
      <xsl:call-template name="getFileData">
        <xsl:with-param name="position" select="position()" />
      </xsl:call-template>
    </xsl:for-each>
    Das Template hat dann noch einmal fileDesc durchlaufen und die Daten wie gewünscht zurück gegeben. Nur habe ich so wesentlich mehr als 20 Einträge, da sich die äußere Schleife nur auf file bezieht und gar nicht mitbekommt, dass ich mit einer inneren Schleife teilweise mehrere parts bearbeite.

    Danach habe ich versucht direkt fileDesc zu durchlaufen - ein count(files/file/fileDesc) gibt sogar die korrekte Gesamtanzahl aller parts an. Jedoch funktioniert da der Trick mit [position() &lt; 21] nicht mehr, da die position sich nun anscheint auf das node file bezieht. [@part &lt; 21] kann ich auch nicht machen, da die parts leider nicht fortlaufend sind und immer wieder Lücken und Sprünge darin vorkommen (sie sind immerhin eindeutig). Ich hab das ganze auch schon einmal mit einem rekursiven Template versucht, allerdings stehe ich da vor dem gleichen Problem.
    Das ganze muss unter XSLT 1.0 funktionieren (keine Ahnung, ob ich mit XSLT 2 mehr Erfolg hätte).

    Kann man das mit XSLT lösen, bzw. kann man mein Problem verstehen? In allen mir bekannten Programmiersprachen wäre es so einfach. Die äußere Schleife müsste nur alle parts mitzählen und nach 20 Stück abbrechen (egal bei welchem Zähler sie gerade steht). Aber das ist ja leider nicht möglich. Ihr seht - ich tue es mir noch sehr schwer mit der XSLT Logik.

    Ich bin für jeden Hinweis mehr als Dankbar!
    Schöne Grüße
    PPP

  • #2
    Mal abgesehen vom nicht wohlgeformten XML-Code lässt sich das Problem ohne xsl:for-each bzw. xsl:call-template ansatzweise so behandeln (fUrl als fileURL aufgefasst):
    Code:
    <xsl:template match="files">
      <html><head><title>Test</title></head>
        <body>
          <xsl:apply-templates select="//fileDesc">
            <xsl:sort select="@part" data-type="number" order="ascending"/>
          </xsl:apply-templates>
        </body>
      </html> 
    </xsl:template>
    
    <xsl:template match="fileDesc">
      <xsl:if test="position() &lt;= 20">
        <div>
          <a id="a_{@part}" href="{preceding-sibling::fileURL}">
            <xsl:value-of select="parent::file/@title"/>
          </a><br />
          <span><xsl:value-of select="."/></span>
        </div>
      </xsl:if>
    </xsl:template>
    Beim span-Inhalt ist noch etwas Feintuning nötig, wenn dort jeweils "Test Nr" stehen soll.

    Comment


    • #3
      Hi, vielen Dank! Mit dem Rest komme ich klar.
      Es ist doch immer wieder schön zu sehen, wie einfach alles ist, wenn man weiß wie es geht. Ich habe mich damit fast 2 Tage herum geplagt und zig verschiedene Lösungsansätze versucht.
      Code:
      <xsl:if test="position() &lt;= 20">
      Das allein hätte mir schon geholfen, denn das funktioniert auch Prima in der Schleife über fileDesc. Allerdings werde ich es nun auch einmal ohne Schleife ausprobieren.

      Vielen, vielen Dank und frohe Ostern!
      PPP

      Comment

      Working...
      X