Создание новой строки в XSLT

Я хочу создать новую строку для вывода текста в XSLT. Любые идеи?

Ответ 1

Следующий код XSL создаст символ newline (строка строки):

<xsl:text>&#xa;</xsl:text>

Для возврата каретки используйте:

<xsl:text>&#xd;</xsl:text>

Ответ 2

Мой любимый метод для этого выглядит примерно так:

<xsl:stylesheet>

<xsl:output method='text'/>

<xsl:variable name='newline'><xsl:text>
</xsl:text></xsl:variable>

<!-- note that the layout there is deliberate -->

...

</xsl:stylesheet>

Затем, когда вы хотите вывести новую строку (возможно, в csv), вы можете вывести что-то вроде следующего:

<xsl:value-of select="concat(elem1,elem2,elem3,$newline)" />

Я использовал эту технику при выводе SQL из ввода XML. На самом деле, я склонен создавать переменные для запятых, кавычек и новых строк.

Ответ 3

Включить атрибут Method = "text" в тег xsl: output и включить новые строки в ваш литеральный контент в XSL в соответствующих точках. Если вы предпочитаете сохранить исходный код вашего XSL-кода, используйте объект &#10;, где вы хотите создать новую строку.

Ответ 4

Вы можете использовать: <xsl:text>&#10;</xsl:text>

см. пример

<xsl:variable name="module-info">
  <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" />
  <xsl:text>&#10;</xsl:text>
</xsl:variable>

если вы пишете это в файле, например.

<redirect:write file="temp.prop" append="true">
  <xsl:value-of select="$module-info" />
</redirect:write>

эта переменная будет выдавать новую строку infile как:

commons-dbcp_commons-dbcp = 1.2.2
junit_junit = 4.4
org.easymock_easymock = 2.4

Ответ 5

IMHO не требуется больше информации, чем @Florjon. Может быть, некоторые мелкие детали оставлены, чтобы понять, почему это может иногда не работать для нас.

Прежде всего, &#xa (hex) или &#10 (dec) внутри a <xsl:text/> всегда будет работать, но вы можете его не увидеть.

  • В HTML-разметке нет новой строки. Использование простого <br/> будет отлично. В противном случае вы увидите пробел. Просмотр источника из браузера скажет вам, что на самом деле произошло. Однако есть случаи, когда вы ожидаете такого поведения, особенно если потребитель не является непосредственно браузером. Например, вы хотите создать HTML-страницу и просмотреть ее структуру, отформатированную с пустыми строками и идентификаторами, прежде чем отправлять ее в браузер.
  • Помните, где вам нужно использовать disable-output-escaping, а где нет. Возьмем следующий пример, когда мне пришлось создать xml из другого и объявить его DTD из таблицы стилей.

Первая версия позволяет избежать символов (по умолчанию для xsl: text)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>

    <xsl:template match="/">
        <xsl:text>&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="copy"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

и вот результат:

<?xml version="1.0" encoding="utf-8"?>
&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;

&#13;<Subscriptions>
    <User id="1"/>   
</Subscriptions>

Хорошо, он делает то, что мы ожидаем, экранирование выполняется так, чтобы символы, которые мы использовали, отображались правильно. Форматирование части XML внутри корня node обрабатывается ident="yes". Но при более близком рассмотрении мы видим, что символ новой строки &#xa не был экранирован и переведен как есть, выполняя двойной перевод строки! У меня нет объяснений по этому поводу, будет полезно знать. Кто угодно?

Вторая версия не убегает от персонажей, поэтому они создают то, для чего они предназначены. Сделано изменение:

<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>

и вот результат:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">

<Subscriptions>
    <User id="1"/>   
</Subscriptions>

и это будет нормально. Оба cr и lf правильно отображаются.

  1. Не забывайте, что мы говорим о nl, а не crlf (nl=lf). Моя первая попытка состояла в том, чтобы использовать только cr: &#xd, а результат xml был правильно проверен DOM.

Я просматривал поврежденный xml:

<?xml version="1.0" encoding="utf-8"?>
<Subscriptions>riptions SYSTEM "Subscriptions.dtd">
    <User id="1"/>   
</Subscriptions>

Парсер DOM игнорировал контрольные символы, но рендеринг не выполнялся. Я потратил довольно много времени, ударяя головой, прежде чем понял, как глупо я этого не видел!

Для записи я использую переменную внутри тела, и оба CRLF должны быть на 100% уверены, что они будут работать везде.

Ответ 6

Я добавил директиву DOCTYPE, которую вы видите здесь:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY nl "&#xa;">
]>
<xsl:stylesheet xmlns:x="http://www.w3.org/2005/02/query-test-XQTSCatalog"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

Это позволяет мне использовать &nl; вместо &#xa; для создания новой строки на выходе. Как и другие решения, это обычно помещается внутри тега <xsl:text>.

Ответ 7

Я нашел разницу между литеральными символами новой строки в <xsl:text> и буквальными символами новой строки, используя &#xA;.

В то время как литературные новые строки отлично работали в моей среде (с использованием как Saxon, так и процессора Java XSLT по умолчанию), мой код не удался, когда он был выполнен другой группой, работающей в среде .NET.

Изменение объектов (&#xA;) привело к тому, что мой код генерации файлов работал последовательно на Java и .NET.

Кроме того, литеральные символы новой строки уязвимы для переформатирования IDE и могут непреднамеренно заблудиться, когда файл поддерживается кем-то, "не знающим".

Ответ 8

По моему опыту я заметил, что создание новой строки INSIDE предложение <xsl:variable> не работает. Я пытался сделать что-то вроде:

<xsl:variable name="myVar">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
      <xsl:text></xsl:text> <!--NEW LINE-->
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

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

Все, что я пытался вставить в эту "новую строку" (пустой <xsl:text> node), просто не работал (включая большинство простых предложений на этой странице), не говоря уже о том, что HTML только что выиграл Я работаю там, поэтому мне пришлось разбить его на 2 переменные, вызвать их вне области <xsl:variable> и поставить между ними простой <br/>, то есть:

<xsl:variable name="myVar1">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<xsl:variable name="myVar2">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

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

Да, я знаю, это не самое сложное решение, но оно работает, просто разделяя мой опыт разочарования с XSLs;)

Ответ 9

Ты можешь попробовать,

<xsl:text>&#xA;</xsl:text>

Это будет работать.

Ответ 10

Второй метод Ника Гибсона, это было всегда мой любимый:

<xsl:variable name='nl'><xsl:text>
</xsl:text></xsl:variable>

Однако я использовал задачу Ant <echoxml> в создавать таблицы стилей и запускать их против файлов. задача будет создавать шаблоны значений атрибутов, например. ${DSTAMP}, но также будет переформатировать ваш xml, поэтому в некоторых случаев, ссылка на объект предпочтительнее.

<xsl:variable name='nl'><xsl:text>&#xa;</xsl:text></xsl:variable>

Ответ 11

Я не мог просто использовать подход <xsl:text>&#xa;</xsl:text>, потому что, если я отформатирую XML файл с помощью XSLT, объект исчезнет. Поэтому мне пришлось использовать немного более крутой подход, используя переменные

<xsl:variable name="nl" select="'&#10;'"/>
<xsl:template match="/">
    <xsl:value-of select="$nl" disable-output-escaping="no"/>
    <xsl:apply-templates select="*"/>
</xsl:template>

Ответ 12

просто добавьте этот тег:

<br/>

он работает для меня;).