Создание новой линии в XSLT - PullRequest
185 голосов
/ 07 апреля 2009

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

Ответы [ 12 ]

224 голосов
/ 19 августа 2010

Следующий XSL-код выдаст символ новой строки (перевод строки):

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

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

<xsl:text>&#xd;</xsl:text>
48 голосов
/ 07 апреля 2009

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

<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-ввода. На самом деле, я склонен создавать переменные для запятых, кавычек и новых строк.

45 голосов
/ 07 апреля 2009

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

26 голосов
/ 04 августа 2011

Вы можете использовать: <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>

эта переменная создаст новую строку в виде:

commons-dbcp_commons-dbcp = 1.2.2
junit_junit = 4.4
org.easymock_easymock = 2.4
5 голосов
/ 29 апреля 2017

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

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

  1. В разметке HTML нет новой строки. Использование простого <br/> подойдет. В противном случае вы увидите пустое пространство. Просмотр источника из браузера покажет вам, что на самом деле произошло. Однако в некоторых случаях вы ожидаете такого поведения, особенно если потребитель не является браузером напрямую. Например, вы хотите создать страницу HTML и просмотреть ее структуру, отформатированную с пустыми строками и идентификаторами, прежде чем отправлять ее в браузер.
  2. Помните, где вам нужно использовать 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-части внутри корневого узла обрабатывается 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% уверенной, что она будет работать везде.

3 голосов
/ 18 июля 2014

Я добавил директиву 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>.

2 голосов
/ 27 июля 2018

Можно попробовать,

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

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

2 голосов
/ 07 октября 2014

По своему опыту я заметил, что создание новой строки 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>), просто не работало (включая большинство простых предложений на этой странице), не говоря уже о том, что 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>

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

2 голосов
/ 28 октября 2013

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

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

При переходе на сущности (&#xA;) мой код генерации файлов работал одинаково на Java и .NET.

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

1 голос
/ 29 апреля 2015

Я не мог просто использовать подход <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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...