Интерпретация новых строк с помощью xsl:текст?

#xml #xslt #ant #xslt-1.0 #whitespace

Вопрос:

У меня есть таблица стилей XSL с содержимым в xsl:text узле, подобном этому:

 <xsl:text>
foo
bar
baz
</xsl:text>
 

Сама таблица стилей представляет собой текстовый файл с терминаторами новой строки в стиле «unix». Я вызываю эту таблицу стилей как на Windows, так и на unix-подобных платформах. Было бы неплохо, чтобы вывод соответствовал соглашениям платформы, на которой он вызывается.

Когда я запускаю эту таблицу стилей в Windows, на выходе отображаются пары возврат каретки/новая строка для всего, кроме содержимого xsl:text узла.

Могу ли я поручить процессору XSLT перевести символы новой строки в содержимом xsl:text узла в конечные строки для конкретной платформы?

Больше контекста: я вызываю таблицу стилей из задачи Apache Ant 1.7.1 XSLT следующим образом:

 <xslt in="in.xml" out="out.xml" style="stylesheet.xsl"/>
 

Заголовок таблицы стилей в настоящее время выглядит следующим образом:

 <?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xslt"
    exclude-result-prefixes="xalan">
    <!-- contents elided -->
</xsl:stylesheet>
 

Ответ №1:

Вы можете определить параметр для таблицы стилей следующим образом:

 <xsl:param name="br">
    <xsl:text>amp;#10;</xsl:text>
</xsl:param>
 

и передайте соответствующий символ(ы) конца строки с помощью вложенного элемента param в вашем сценарии Ant. По умолчанию в этом примере, конечно, будет новая строка в стиле Unix. Я думаю, что для вывода значения вам придется использовать:

 <xsl:copy-of select="$br"/>
 

Это многословно, но это работает.

Комментарии:

1. Спасибо за ответ! Это хорошая идея, но я не думаю, что xsl:копия может быть встроена в текст xsl:text. Можно ли вместо этого определить сущность с помощью параметра? Я могу вставлять такие вещи, как Как это делается? В идеале, я бы хотел, чтобы это можно было сделать, не передавая EOL через параму.

2. Почему это должно быть внутри xsl:текста? Почему бы не несколько

Ответ №2:

Если вы вызываете преобразование из Ant, то вы можете протестировать ОС с помощью условной задачи с тестом для семейства ОС:

   <condition property="linebreak" value="amp;#xD;amp;#xa;">
      <os family="windows"/>
  </condition>
  <condition property="linebreak" value="amp;#xa;">
      <os family="unix"/>
  </condition>
 

Затем передайте этот параметр в XSLT, чтобы указать, какие символы новой строки вы хотите использовать.

  <xslt in="data.xml" out="${out.dir}/out.xml">
   <param name="linebreak" expression="${linebreak}" />
 </xslt>
 

Ответ №3:

Я не знаю, как автоматически вводить новые строки (это может зависеть от используемого вами процессора xslt), но вы можете принудительно вводить новые строки в содержимое текстового узла. rn есть amp;#xD; amp;#xA; , n есть amp;#xA; , например, вы бы использовали:

<xsl:text>fooamp;#xD;amp;#xa;baramp;#xD;amp;#xa;</xsl:text> чтобы получить результат, который вы ищете.

Комментарии:

1. Спасибо за ответ! Да, я думаю, что я мог бы это сделать, но тогда вывод был бы неправильным в unix-подобных средах! Вместо того, чтобы жестко кодировать его так или иначе, я хочу, чтобы он «делал правильные вещи» независимо от того, где он вызывается. Может быть, мне следует уточнить это в вопросе. Еще раз спасибо.

Ответ №4:

Ну, я получил свое для работы (используя саксонский) с комбинацией из 2 идей выше:

 <xsl:param name="br">
        <xsl:text>amp;#xD;amp;#xa;</xsl:text>
</xsl:param>
 

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

 <xsl:value-of select="$br" />
 

Вот мой полный (но тонкий) xsl

 <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!--<xsl:strip-space elements="*" />-->
  <xsl:output method="text" />
  <!-- <xsl:preserve-space elements="*"/>-->
<xsl:param name="br">
        <xsl:text>amp;#xD;amp;#xa;</xsl:text>
</xsl:param>


  <!--  -->
  <xsl:template match="/">


    <xsl:for-each select="//root/Item">

        <xsl:value-of select="@Name" /> <!-- Your xpath will vary of course! -->
        <xsl:value-of select="$br" />

    </xsl:for-each>

</xsl:template>
 

Опять же, я использую саксонский
%ProgramFiles%SaxonHEbinTransform.exe
на компьютере с Windows 7 x64.