Как сохранить переводы строк, табуляции и пробелы в данных, сохраняя при этом перенос текста? - PullRequest
2 голосов
/ 18 сентября 2008

У меня были данные в XML, содержащие переводы строк, пробелы и табуляции, которые я хотел сохранить в выходном HTML (поэтому я не мог использовать

), но я также хотел, чтобы строки переносились, когда сторона экран был достигнут (поэтому я не мог использовать

). 

Ответы [ 4 ]

1 голос
/ 18 сентября 2008

Другой способ выразить это в том, что вы хотите превратить все пары пробелов в два неразрывных пробела, табуляции в четыре неразрывных пробела и все разрывы строк в <br> элементах. В XSLT 1.0 я бы сделал:

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

Невозможность использовать хвостовую рекурсию - это немного больно, но это не должно быть реальной проблемой, если текст не очень длинный.

Решение XSLT 2.0 будет использовать <xsl:analyze-string>.

0 голосов
/ 18 сентября 2008

Действительно, я бы выбрал редактор, который поддерживает это правильно, вместо того, чтобы разбираться с большим количеством XML.

0 голосов
/ 18 сентября 2008

Не уверен, что это актуально, но разве нет атрибута preservepace и еще много чего для xml?

0 голосов
/ 18 сентября 2008

Я и его коллега (Патриция Эромоселе) придумали следующее решение: (Есть ли лучшее решение?)

    <p><br />                    <xsl:call-template name="prewrap"><br />                      <xsl:with-param name="text" select="text"/><br />                    </xsl:call-template><br />    </p><br /><br /> <br /> <br />    <xsl:template name="prewrap"><br />     <xsl:param name="text" select="."/><br />     <xsl:variable name="spaceIndex" select="string-length(substring-before($text, '  '))"/><br />     <xsl:variable name="tabIndex" select="string-length(substring-before($text, '&#x09;'))"/><br />     <xsl:variable name="lineFeedIndex" select="string-length(substring-before($text, '&#xA;'))"/><br />     <xsl:choose><br />       <xsl:when test="$spaceIndex = 0 and $tabIndex = 0 and $lineFeedIndex = 0"><!-- no special characters left --><br />           <xsl:value-of select="$text"/><br />       </xsl:when><br />       <xsl:when test="$spaceIndex > $tabIndex and $lineFeedIndex > $tabIndex"><!-- tab --><br />         <xsl:value-of select="substring-before($text, '&#x09;')"/><br />         <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><br />         <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><br />         <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><br />         <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><br />         <xsl:call-template name="prewrap"><br />           <xsl:with-param name="text" select="substring-after($text,'&#x09;')"/><br />         </xsl:call-template><br />       </xsl:when><br />       <xsl:when test="$spaceIndex > $lineFeedIndex and $tabIndex > $lineFeedIndex"><!-- line feed --><br />         <xsl:value-of select="substring-before($text, '&#xA;')"/><br />         <br/><br />         <xsl:call-template name="prewrap"><br />           <xsl:with-param name="text" select="substring-after($text,'&#xA;')"/><br />         </xsl:call-template><br />       </xsl:when><br />       <xsl:when test="$lineFeedIndex > $spaceIndex and $tabIndex > $spaceIndex"><!-- two spaces --><br />         <xsl:value-of select="substring-before($text, '  ')"/><br />         <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><br />         <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><br />         <xsl:call-template name="prewrap"><br />           <xsl:with-param name="text" select="substring-after($text,'  ')"/><br />         </xsl:call-template><br />       </xsl:when><br />       <xsl:otherwise><!-- should never happen --><br />           <xsl:value-of select="$text"/><br />       </xsl:otherwise><br />     </xsl:choose><br />    </xsl:template>

Источник: http://jamesjava.blogspot.com/2008/06/xsl-preserving-line-feeds-tabs-and.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...