views:

59

answers:

2

There is a code:

<p>
    Lorem ipsum dolor sit ametconsecteturadipisicing elit, 
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco 
    laboris nisi ut aliquip ex ea commodo consequat. 
    Duis aute iruredolorinreprehenderit in voluptate 
    velit esse cillum doloreeufugiatnullapariatur. Excepteur sint 
    occaecat cupidatat non proident, sunt in culpa qui officia 
    deserunt mollit anim id est laborum.
</p>

It is necessary to receive:

<p>
    Lorem ipsum dolor sit <span class="spaced">a m e t c o n s e c t e t u r a d i p i s i c i n g</span> elit, 
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco 
    laboris nisi ut aliquip ex ea commodo consequat. 
    Duis aute <span class="spaced">i r u r e d o l o r i n r e p r e h e n d e r i t</span> in voluptate 
    velit esse cillum <span class="spaced">d o l o r e e u f u g i a t n u l l a p a r i a t u r</span>. Excepteur sint 
    occaecat cupidatat non proident, sunt in culpa qui officia 
    deserunt mollit anim id est laborum.
</p>

The sense consists in dividing "long" words with spaces. To put space after each letter in such word. Then it is necessary to conclude this word in a tag with a class "spaced".

The word is considered "long" if the quantity of letters in this word is more 10 (for example. It is possible to set any value).

How to solve this problem means xslt?

+3  A: 

Here is an XSLT 2.0 stylesheet that you could run with Saxon 9 or with AltovaXML tools:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xsd"
  version="2.0">

  <xsl:param name="l" as="xsd:integer" select="10"/>
  <xsl:variable name="regex1" as="xsd:string" select="concat('\w{', $l, ',}')"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*, node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="p/text()">
    <xsl:analyze-string select="." regex="{$regex1}">
      <xsl:matching-substring>
        <span class="space">
          <xsl:value-of select="for $ c in string-to-codepoints(.) return codepoints-to-string($c)"
                        separator=" "/>
        </span>
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="."/>
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:template>

</xsl:stylesheet>
Martin Honnen
@Martin Honnen, this code will work only on processor wich supports XSLT 2.0? Is there any solution on XSLT 1.0? We did not have XSLT 2.0 on our server.
Kalinin
You will indeed need an XSLT 2.0 processor to run that stylesheet. As for a pure XSLT 1.0 solution, I don't have one. As you can see the XSLT 2.0 solution makes use of regular expressions which pure XSLT 1.0 does not support at all. If you really want to solve that with XSLT 1.0 then I would at least check whether your XSLT 1.0 processors supports regular expressions as an extension.
Martin Honnen
@Martin Honnen,libxslt Version 1.1.17,libxslt compiled against libxml Version 2.6.26,EXSLT - enabled,libexslt Version - 1.1.17.this our xslt settings on server.
Kalinin
A: 

Very clever people have prompted me the decision, huge to them thanks. Works in xslt 1.0 without any extansions. It is not my solution.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns="http://www.w3.org/1999/xhtml"&gt;
        <xsl:output method="xml" media-type="text/xhtml" version="1" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

    <xsl:template match="p">
      <p>
        <xsl:call-template name="tokens">
          <xsl:with-param name="str" select="text()" />
        </xsl:call-template>
      </p>
    </xsl:template>  

    <xsl:template name="tokens">
      <xsl:param name="str" />
      <xsl:choose>
        <xsl:when test="contains($str, ' ')">
          <xsl:call-template name="checklength">
            <xsl:with-param name="str" select="substring-before($str, ' ')" />
          </xsl:call-template>
          <xsl:call-template name="tokens">
            <xsl:with-param name="str" select="substring-after($str, ' ')"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="checklength">
            <xsl:with-param name="str" select="$str" />
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

    <xsl:template name="checklength">
      <xsl:param name="str" />
      <xsl:choose>
        <xsl:when test="string-length($str) &gt; 10">
          <span class="spaced">
            <xsl:call-template name="insertspaces">
              <xsl:with-param name="str" select="$str" />
            </xsl:call-template>
          </span>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$str" />
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text> </xsl:text>
    </xsl:template>

    <xsl:template name="insertspaces">
      <xsl:param name="str" />
      <xsl:choose>
        <xsl:when test="string-length($str) &gt; 1">
          <xsl:value-of select="substring($str, 1, 1)" /><xsl:text> </xsl:text>
          <xsl:call-template name="insertspaces">
            <xsl:with-param name="str" select="substring($str, 2, string-length($str) - 1)" />
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$str" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
Kalinin