Stefan H.: Zeilenumbruch im XSL beibehalten

Hallo,

ich bin momentan am schreiben einer XSL-Ausgabe für meine XML-Daten und stehe vor folgendem Problem:

Die Seite funktioniert an sich wunderbar, jedoch übernimmt mein Code bei der Transformation durch XSLT in HTML keine Zeilenumbrüche. Die eingegeben Daten z.b...

Hallo du,

heute gehen wir schwimmen.

Gruß Boris

... werden mir später dann als Hallo du,heute gehen wir schwimmen.Gruß Boris ... ausgegeben.

Ich hatte mich zu diesem Thema schon hier im Forum informiert und auch schon eine Antwort gesehen, jedoch brachte sie mich in meinem speziellen Fall nicht weiter.

Um noch ein paar additionale Informationen zu geben:

Die Verschachtelung ist folgende:

<!element nr1 (nr2)>
<!element nr2 (nr3, nr4, nr5 ...)>
<!element nr3 (#pcdata)>
<!element nr4 (#pcdata)>
...

Meine Frage ist also:
Wie muss mein Code lauten, um Zeilenumbrüche (die in den XML Daten gespeichert sind) dann auch bei der Ausgabe durch XSL beizubehalten.

Ich hoffe, dass mir jemand weiterhelfen kann und bedanke mich im vorraus.

Liebe Grüße,

Stefan

  1. der xml teil:

    <element>
     hallo du,<umbruch /><umbruch />
     heute gehen wir schwimmen.<umbruch /><umbruch />
     Gruß Boris
    </element>

    der xsl teil

    <xsl:template match="element">
     <div>
      <xsl:apply-templates />
     </div>
    </xsl:template>

    <xsl:template match="umbruch">
     <br />
    </xsl:template>

    bütte sehr:D
    hab ca 6 monate gebraucht um das alleine rauszufinden imw ebs teht echt NIX dazu...

    1. Danke Booker für deine schnelle Antwort. Das Problem an deiner Lösung ist jedoch folgendes:

      Die XML Datei auf die sich meine XSL Datei bezieht wird automatisch geschrieben und ist abhängig von der Eingabe des Users. Das bedeutet folgendes:

      Ein User gibt über eine Oberfläche Daten in vordefinierte Objekte ein. Diese Daten werden dann als Werte in eine XML Datei gespeichert. Und diese Werte werden dann durch meine XSL Datei ausgegeben. Das bedeutet, dass ich einen Code brauche, der automatisch erkennt WANN der User einen Zeilenumbruch benutzt, da diese in nicht vorbestimmbarer Reihenfolge und Menge vorkommen können.

      Gruß Stefan

      1. ehm soweit ich das richtig verstehe...ehm müsstest du dann der "oberfläche" sagen das wenn der User "enter" eingibt er ein in xsl definiertes element<umbruch /> setzt?

        wasn dis für ne oberfläche? kannst der sowas sagen? ansonsten hat es leider nix mit xml zu tun befürchte ich...

        denküberlegung programier routine:

        if user drückt enter setze <umbruch /> element
        ...

        vielleicht hilft es wenn ich ein Beispiel mit der Oberfläsche hätte:D

        1. Ja so ungefähr sieht das Problem aus. Also zum besseren Verständnis...

          Der User ist auf einer Seite und kann dort über Drop-Down-Menus bestimmte Angaben über sein Problem machen. So kann er z.B. "System" anwählen und hat dort bestimmte Auswahlmöglichkeiten. Der User hat aber auch bestimmte Textfelder in denen er ein Problem genauer beschreiben kann.

          Also z.B. System (er wählt aus) Citrix, Produkt (er wählt aus) Perl und als Text gibt er ein:

          Habe ein Problem im Citrix.

          blablabla

          So, in der XML wird nun geschrieben

          <system> Citrix </system>
          <product> Perl </product>
          <short_descr> Habe ein Problem im Citrix[]blablabla<short_descr>

          das [] steht für den Zeilenumbruch. Der wird dann in der XML als [] geschrieben.

          So, nun musste der Bearbeiter des Fehlers die vom User eingegeben Daten genau so lesen. Nämlich als reine XML-Datenstruktur

          <product> perl </product>
          etc..

          Um dies zu verschönern habe ich die XML mit einer XSL verbunden, um eine HTML Ausgabe der Daten zu erzwingen, damit es benutzerfreundlicher zu lesen ist. Das Problem (wie beschrieben) ist aber, dass in der HTML Ausgabe der XML Daten diese Umbrüche nicht erkannt werden -> Ausgabe daher: Habe ein Problem im Citrixblablabla

          Du hast also mit deiner Beschreibung "if benutzer drückt enter ..." recht. Er muss die Zeilenumbrüche erkennen und den Text in der XSL / HTML Ausgabe dann genau so wiedergeben.

          Hoffe meine Beschreibung erklärt das Problem etwas genauer.

          Danke im Vorraus und Gruß

          1. Hallo,

            Er muss die Zeilenumbrüche erkennen und den Text in der XSL / HTML Ausgabe dann genau so wiedergeben.

            Der Thread http://forum.de.selfhtml.org/archiv/2006/4/t128430/#m829835 sollte dir weiterhelfen.
            Falls nicht, hier bitte nachfragen.

            Grüße
            Thomas

            1. Hallo Thomas, danke dir für die Antwort, ein Problem habe ich trotzdem noch. Mein Code sieht wie folgt aus:

              <div id="conmain">
                        <xsl:for-each select="bugzilla/bug/long_desc">
                         <br/>
                          <p>
                           <b><xsl:value-of select="who" /> -
                            </b>
                           <b>
                            <xsl:value-of select="substring(bug_when, 9, 2)" />.
                            <xsl:value-of select="substring(bug_when, 6, 2)" />.
                            <xsl:value-of select="substring(bug_when, 1, 4)" /> -
                     <xsl:value-of select="substring(bug_when, 12)" />
                           </b>
                          </p>
                  <br/>
                          <p>
                           <b><xsl:value-of select="thetext" />
                           </b>
                          </p>
                         <hr/>
                        </xsl:for-each>
                        </div>
                       </div>
                      </body>
                     </html>
                    </xsl:template>
                   </xsl:stylesheet>

              Bitte nicht über den Code wundern, hab das mit einem Kollegen gemacht und wir sind beides XML Anfänger :-) Jedenfalls funktioniert die Datei als solches wunderbar. Wir haben jetzt aber das Problem, dass der Text der bei <xsl:value-of select="thetext" /> ausgegeben werden soll unformatiert ist. Soll heissen, dass er genau an der Stelle die leerzeichen beachten soll.
              So nun hab ich das Problem, dass ich kein weiteres Template in das Template verschachteln kann, weil er mir dann den Fehler "xsl:template hier nicht erlaubt" ausgibt.
              Meine Überlegung: Kann ich ein eigenes Template anlegen mit deinen Daten und das dann mit meiner XSLT verlinken? Wenn ja, wie definiere ich die verlinkung einer "zweiten XSL" Datei? Hatte ich mal ausprobiert hat aber nicht so ganz funktioniert... hoffe das erklärt das Problem etwas genauer. grüße

              1. Hallo,

                Hallo Thomas, danke dir für die Antwort, ein Problem habe ich trotzdem noch. Mein Code sieht wie folgt aus:

                Wir haben jetzt aber das Problem, dass der Text der bei <xsl:value-of select="thetext" /> ausgegeben werden soll unformatiert ist. Soll heissen, dass er genau an der Stelle die leerzeichen beachten soll.
                So nun hab ich das Problem, dass ich kein weiteres Template in das Template verschachteln kann, weil er mir dann den Fehler "xsl:template hier nicht erlaubt" ausgibt.
                Meine Überlegung: Kann ich ein eigenes Template anlegen mit deinen Daten und das dann mit meiner XSLT verlinken? Wenn ja, wie definiere ich die verlinkung einer "zweiten XSL" Datei? Hatte ich mal ausprobiert hat aber nicht so ganz funktioniert... hoffe das erklärt das Problem etwas genauer.

                alles nicht nötig: einfach das Template an der richtigen Stelle einfügen und an der richtigen Stelle aufrufen:
                (&#xA; ist das Zeichen für Zeilenvorschub (Zeilenumbruch), wenn ihr da keinen echten Zeilenumbruch verwendet, sondern irgendwelche eigene Zeichen, muss du dass im Template entsprechend ändern)

                Grüße
                Thomas

                <div id="conmain">
                          <xsl:for-each select="bugzilla/bug/long_desc">
                           <br/>
                            <p>
                             <b><xsl:value-of select="who" /> -
                              </b>
                             <b>
                              <xsl:value-of select="substring(bug_when, 9, 2)" />.
                              <xsl:value-of select="substring(bug_when, 6, 2)" />.
                              <xsl:value-of select="substring(bug_when, 1, 4)" /> -
                       <xsl:value-of select="substring(bug_when, 12)" />
                             </b>
                            </p>
                    <br/>
                            <p>
                             <b>

                <!-- <xsl:value-of select="thetext" /> -->
                <xsl:call-template name="cr2br>
                  <xsl:with-param name="text" select="thetext" />
                </xsl:call-template>

                </b>
                            </p>
                           <hr/>
                          </xsl:for-each>
                          </div>
                         </div>
                        </body>
                       </html>
                      </xsl:template>

                <xsl:template name="cr2br">
                 <xsl:param name="text" />
                 <xsl:variable name="textafterbreak" select="substring-after($text, '&#xA;')" />
                 xsl:choose
                  <xsl:when test="contains($text, '&#xA;')">
                   <xsl:value-of select="substring-before($text, '&#xA;')" />
                   <br />
                   <xsl:call-template name="cr2br">
                   <xsl:with-param name="text" select="$textafterbreak" />
                   </xsl:call-template>
                  </xsl:when>
                  xsl:otherwise
                   <xsl:value-of select="$text" />
                  </xsl:otherwise>
                 </xsl:choose>
                </xsl:template>

                </xsl:stylesheet>

                1. Danke Thomas, du bist wirklich Gold wert :-) Wünsche euch allen frohe Ostern und nochmals danke für die kompetente, hilfreiche und nette Antwort! Grüße

                2. Hallo ihr,
                  hab das jetzt ausprobiert und er gibt mir folgende Fehlerausgabe

                  Das Zeichen '<' kann in einem Attributwert nicht verwendet werden. Fehler beim Bearbeiten der Ressource 'file:///C:/Dokumen...

                  <xsl:with-param name="text" select="thetext" />
                  -------------^

                  Hatte den Code so übernommen, wie du mir die Templates in den vorhandenen Code reingelegt hast, Thomas, aber irgendwie stört ihn was an dem < obwohl mir schleierhaft ist, wieso eigentlich... Alles ist ordnungsgemäß geschlossen und läuft nur passt ihm anscheinend irgendwas nicht...

                  1. Funktioniert! Vielen, vielen Dank an alle Beteiligten für die Hilfe, besonders an Thomas... Gruß Stefan

                3. Ok, ich glaub ich hab den Fehler... ein " hat gefehlt :-) deswegen dachte er auch, dass das < in einem attributwert vorkommt

                  1. Hallo,

                    Ok, ich glaub ich hab den Fehler... ein " hat gefehlt :-)

                    Jepp, bei » name="cr2br> «.

                    Grüße
                    Thomas

            2. jo das geht super musst halt nur content durch short_descr und die codirung gegen [] austauschen...nice:D

              xsl:

              so:D

              <?xml version="1.0" encoding="iso-8859-1"?>
              <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
              <xsl:output method="html"/>
               <xsl:template match="/">
                <html>
                 <head>
                  <title>test</title>
                 </head>
                 <body>
                  <xsl:apply-templates />
                 </body>
                </html>
               </xsl:template>

              <xsl:template match="short_descr">
                <xsl:apply-templates />
              </xsl:template>

              <xsl:template match="short_descr/text()">
                <xsl:call-template name="cr2br">
                 <xsl:with-param name="text" select="." />
                </xsl:call-template>
              </xsl:template>

              <xsl:template name="cr2br">
               <xsl:param name="text" />
               <xsl:variable name="textafterbreak" select="substring-after($text, '[]')" />
               xsl:choose
                <xsl:when test="contains($text, '[]')">
                 <xsl:value-of select="substring-before($text, '[]')" />
                 <br />
                 <xsl:call-template name="cr2br">
                 <xsl:with-param name="text" select="$textafterbreak" />
                 </xsl:call-template>
                </xsl:when>
                xsl:otherwise
                 <xsl:value-of select="$text" />
                </xsl:otherwise>
               </xsl:choose>
              </xsl:template>

              </xsl:stylesheet>

              dein root element sieht aber glaube anders aus ansonsten müsste es passen:D

          2. xml:

            <?xml version="1.0" encoding="iso-8859-1"?>
            <?xml-stylesheet type="text/xsl" href="test.xsl"?>
            <short_descr> Habe ein Problem im Citrix[]blablabla[]muh[]mäh</short_descr>

            xsl:

            <?xml version="1.0" encoding="iso-8859-1"?>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:output method="html"/>
             <xsl:template match="/">
              <html>
               <head>
                <title>test</title>
               </head>
               <body onclick="test()">
               <script type="text/javascript">
                 function test() {
                          ersetze_muh = document.getElementById("test").firstChild.nodeValue.replace(/[]/g, "&lt;br /&gt;");
                          document.write(ersetze_muh);
                          return true;
                                  }

            </script>
               <xsl:apply-templates />
               </body>
              </html>
             </xsl:template>

            <xsl:template match="short_descr">
             <div id="test" style="position:relative;left:40%;">
              <xsl:value-of select="." />
             </div>
            </xsl:template>
            </xsl:stylesheet>

            so ich mach erstmal pause mein kopf raucht...
            habe es mit xsl/xml/xPath probiert aber da keine schleife hinbekommen sondern nur das erste [] rausgefiltert bekommen...
            vieleicht probeir du mal mit dem leicht buggy ansatz mal was...
            problem...
            1. funst im IE nicht aber kann man ja abfangen...
            2. irgentwie kommt der script nicht zum ende..mit anderen worten läst seite manschmal abstürzen..
            3.das write hat keine element zuordnung, d.h...er schreibts bei position 0 0 hin:D
            <-macht ne pause:D

            1. ups paar sachen hab ich zu testzwecken geändert...müsstest rückrängig machen:D

              1. aus onload=onclick machen
              1. die css formatierung is relativ unwichtig:D