Announcement

Collapse
No announcement yet.

String nach bestimmter Anzahl Zeichen trennen

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

  • String nach bestimmter Anzahl Zeichen trennen

    Hallo Zusammen,

    ich habe folgendes Problem:
    Ich habe einen ziemlich langen String (einzelne Wörter sind mit Unterstrich verbunden, der String hat kein einziges Leerzeichen) und möchte in diesen nach einer bestimmten Anzahl Zeichen ein Leerzeichen einfügen. Grund: Damit er in einer Tabelle entsprechend umgebrochen wird ohne dass sich die Zeichen über über die nächsten Spalte mit schieben und dort der Text unleserlich ist, weil sich die Wörter überlagern.
    Wie bekomme ich sowas am geschicktesten hin?

    String ist bspw.:
    Code:
    Ich_bin_ein_ziemlich_langer_Text_der_kein_Leerzeichen_hat__das_ist_schade
    Das Leerzeichen soll nach jeweils immer 20 Zeichen eingefügt werden.

    Mein bisheriger Ansatz fügt bisher immer nur nach den ersten 20 Zeichen ein Leerzeichen ein. Ich weiß nicht, wie ich das rekursiv hinbekomme.

    Code:
    <xsl:template name="hardLineBreak">
        <xsl:param name="breakAfterCharacters"/>
      	<xsl:param name="textToBreak"/>
      	<xsl:choose>
      	  	<xsl:when test="contains($textToBreak,' ')">
     	  		<xsl:value-of select="$textToBreak" />
      	  	</xsl:when>
    	  	<xsl:when test="string-length($textToBreak)">
    	  	  <xsl:variable name="laenge" select="string-length($textToBreak)" />
    	       <xsl:variable name="vor" select="substring($textToBreak,1,$breakAfterCharacters)" />
    	       <xsl:variable name="nach" select="substring($textToBreak,$breakAfterCharacters,$laenge)" />
    	       <xsl:variable name="erg" select="concat($vor, ' ', $nach)" />
    	       <xsl:if test="string-length($textToBreak) &gt; ($breakAfterCharacters * 2)">	       
    	       </xsl:if>
    	       </xsl:when>
    	    <xsl:otherwise>
    	    	<xsl:value-of select="$textToBreak" />
    	    </xsl:otherwise>
    	</xsl:choose>
    </xsl:template>
    Der Aufruf erfolgt so hier:
    Code:
    <xsl:call-template name="hardLineBreak">
       <xsl:with-param name="breakAfterCharacters" select="$iLinebreakAfterCharacter"/>
       <xsl:with-param name="textToBreak" select="'Ich_bin_ein_ziemlich_langer_Text_der_kein_Leerzeichen_hat__das_ist_schade'"/>
    </xsl:call-template>
    Gruß,
    MAF1981

  • #2
    Mit XSLT 2.0:
    Code:
    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="2.0">
      
      <xsl:param name="n" select="5"/>
      
      <xsl:template match="test">
        <xsl:copy>
          <xsl:analyze-string select="." regex=".{{1,{$n}}}">
            <xsl:matching-substring>
              <xsl:value-of select="concat(., ' ')"/>
            </xsl:matching-substring>
          </xsl:analyze-string>
        </xsl:copy>
      </xsl:template>
      
    </xsl:stylesheet>
    Damit macht Saxon 9 (http://saxon.sourceforge.net/) aus
    Code:
    <test>Ich_bin_ein_ziemlich_langer_Text_der_kein_Leerzeichen_hat__das_ist_schade</test>
    folgendes:
    Code:
    <?xml version="1.0" encoding="UTF-8"?><test>Ich_b in_ei n_zie mlich _lang er_Te xt_de r_kei n_Lee rzeic hen_h at__d as_is t_sch </test>
    Den Parameter, den ich als 5 gewählt habe, kannst du natürlich dann auf 20 setzen.
    Zuletzt editiert von Martin Honnen; 02.03.2011, 18:47. Reason: Verbesserung, um nicht am Ende einen Teil des Textes abzuschneiden

    Comment


    • #3
      Hallo,

      vielen Dank erstmal.
      Leider kann ich nur XSLT 1.0 verwenden...

      Comment


      • #4
        Hier ist ein XSLT 1.0 Stylesheet:
        Code:
        <xsl:stylesheet
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          version="1.0">
          
          <xsl:param name="n" select="5"/>
          
          <xsl:template name="split">
            <xsl:param name="text"/>
            <xsl:param name="size"/>
            <xsl:param name="separator" select="' '"/>
            <xsl:choose>
              <xsl:when test="string-length($text) &lt;= $size">
                <xsl:value-of select="$text"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="concat(substring($text, 1, $size), $separator)"/>
                <xsl:call-template name="split">
                  <xsl:with-param name="text" select="substring($text, $size + 1)"/>
                  <xsl:with-param name="size" select="$size"/>
                  <xsl:with-param name="separator" select="$separator"/>
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:template>
          
          <xsl:template match="test">
            <xsl:copy>
              <xsl:call-template name="split">
                <xsl:with-param name="text" select="."/>
                <xsl:with-param name="size" select="$n"/>
              </xsl:call-template>
            </xsl:copy>
          </xsl:template>
          
        </xsl:stylesheet>

        Comment


        • #5
          Hallo,

          vielen Dank, aber irgendwie habe ich noch ein Problem beim Aufruf:

          Code:
               <fo:table-cell xsl:use-attribute-sets="tableCell">
                    <fo:block id="test">
                            <xsl:value-of select="$MeasurementChart"/>
                     </fo:block>
               </fo:table-cell>
          Oder funktioniert das so nicht?

          Comment


          • #6
            Ich verstehe den Bezug der letzten Frage zur ursprünglichen nicht. Wie man das Template mit dem Namen "split" in XSLT aufruft, zeigt mein Beispiel doch:
            Code:
              <xsl:template match="test">
                <xsl:copy>
                  <xsl:call-template name="split">
                    <xsl:with-param name="text" select="."/>
                    <xsl:with-param name="size" select="$n"/>
                  </xsl:call-template>
                </xsl:copy>
              </xsl:template>
            "test" ist dabei ein Element im XML-Eingabedokument, das den Text enthält, der in einzelene Teile zerlegt werden soll.

            Comment


            • #7
              Hi,
              ja, das habe ich gesehen, leider stehe ich auf dem Schlauch, was es angeht den Aufruf für meine Zwecke umzubauen bzw. es in meinem XSLT überhaupt aufzurufen. Ich bekomme meist ein "Could not compile stylesheet"

              Ich erzeuge eine Tabelle und dort sollen mehrere Spalten (die so einen langen Wert haben können) gesplittet werden. Wie rufe ich da dein Template auf?
              Code:
              ...
                <fo:table-cell xsl:use-attribute-sets="tableCell">
                    <fo:block id="test">
                           <xsl:value-of select="MeasurementChart"/>
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="tableCell">
                    <fo:block id="test">
                           <xsl:value-of select="SourcingOffice"/>
                    </fo:block>
                </fo:table-cell>
               ...
              Ich hätte gedacht, das funktioniert u.a. mit der Angabe einer Id, siehe vorherigen Beitrag. Aber leider hab ich da wohl falsch gedacht.

              Comment


              • #8
                Statt
                Code:
                <xsl:value-of select="MeasurementChart"/>
                benutze halt call-template:
                Code:
                      <xsl:call-template name="split">
                        <xsl:with-param name="text" select="MeasurementChart"/>
                        <xsl:with-param name="size" select="20"/>
                      </xsl:call-template>

                Comment

                Working...
                X