XSLT: добавить пробелы в «длинном» слове - PullRequest
1 голос
/ 31 марта 2010

Есть код:

<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>

Необходимо получить:

<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>

Смысл состоит в делении"длинных" слов с пробелами . Поставить пробел после каждой буквы в таком слове. Затем необходимо заключить это слово в тег с классом "интервал".

Слово считается «длинным», если количество букв в этом слове больше 10 (например, можно задать любое значение).

Как решить эту проблему означает xslt ?

Ответы [ 2 ]

3 голосов
/ 31 марта 2010

Вот таблица стилей XSLT 2.0, которую можно запустить с Saxon 9 или с 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>
0 голосов
/ 01 апреля 2010

Очень умные люди подсказали мне решение, огромное им спасибо. Работает в xslt 1.0 без каких-либо расширений. Это не мое решение.

<?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">
        <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>
...