Не удается получить xslt для вывода (&) даже после экранирования символа - PullRequest
19 голосов
/ 16 сентября 2008

Я пытаюсь создать строку запроса переменных назначений, разделенных символом & (например: "var1=x&var2=y&..."). Я планирую передать эту строку во встроенный флэш-файл.

У меня проблемы с отображением символа & в XSLT. Если я просто наберу & без тегов, возникнет проблема с отображением документа XSLT. Если я наберу &amp; без тегов вокруг него, то вывод документа будет &amp; без изменений. Если я наберу <xsl:value-of select="&" /> или <xsl:value-of select="&amp;" />, я также получу ошибку. Это возможно? Примечание: я также пробовал &amp;amp; безуспешно.

Ответы [ 13 ]

17 голосов
/ 27 сентября 2008

Вы можете комбинировать disable-output-escaping с секцией CDATA. Попробуйте это:

<xsl:text disable-output-escaping="yes"><![CDATA[&]]></xsl:text>
12 голосов
/ 13 октября 2015

Я пытаюсь создать строку запроса переменных назначений, разделенных по символу & (например: "var1=x&var2=y&..."). Я планирую передать это строка во встроенный флэш-файл.

У меня проблемы с отображением символа & в XSLT.

Вот примерная, краткая и полная демонстрация того, как создать такой URL:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vX" select="'x'"/>
 <xsl:variable name="vY" select="'y'"/>
 <xsl:variable name="vZ" select="'z'"/>

  <xsl:template match="/">
    <xsl:value-of select=
"concat('http://www.myUrl.com/?vA=a&amp;vX=', $vX, '&amp;vY=', $vY, '&amp;vZ=', $vZ)"/>
  </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к любому исходному XML-документу (игнорируется) :

<t/>

желаемый, правильный результат получается:

http://www.myUrl.com/?vA=a&vX=x&vY=y&vZ=z

Что касается других вопросов, поднятых в вопросе:

Если я наберу &amp; без тегов, то вывод документ &amp; без изменений.

Вышеприведенное утверждение просто не соответствует действительности ... Просто запустите приведенное выше преобразование и посмотрите на результат.

Что на самом деле происходит :

Результат, который вы видите, абсолютно верен, однако ваш метод вывода - html или xml (значение по умолчанию для method=), поэтому сериализатор процессора XSLT должен представлять правильный результат - строку http://www.myUrl.com/?vA=a&vX=x&vY=y&vZ=z - как (часть) текстового узла в правильно сформированном документе XML или в дереве HTML.

По определению в правильно сформированном XML-документе буквальный амперсанд должен экранироваться символьной ссылкой, такой как встроенная &amp; или &#38;, или &#x26;

Помните : строка, представленная как (часть) текстового узла XML или внутри дерева HTML, может не выглядеть как одна и та же строка при представлении в виде текста. Тем не менее, это два разных представления одной и той же строки.

Чтобы лучше понять этот простой факт, сделайте следующее :

Возьмите приведенное выше преобразование и замените объявление xsl:output:

 <xsl:output method="text"/>

с этим:

 <xsl:output method="xml"/>

Кроме того, заключите вывод в один элемент XML. Вы также можете попытаться использовать различные экранированные символы для амперсанда. Теперь трансформация может выглядеть так:

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

 <xsl:variable name="vX" select="'x'"/>
 <xsl:variable name="vY" select="'y'"/>
 <xsl:variable name="vZ" select="'z'"/>

  <xsl:template match="/">
        <t>
            <xsl:value-of select=
 "concat('http://www.myUrl.com/?vA=a&amp;vX=', $vX, '&#38;vY=', $vY, '&#x26;vZ=', $vZ)"/>
        </t>
  </xsl:template>
</xsl:stylesheet>

И результат :

<t>http://www.myUrl.com/?vA=a&amp;vX=x&amp;vY=y&amp;vZ=z</t>

Вы получите тот же результат с методом вывода html.

Вопрос

Является ли URL-адрес, который выводится, отличным (или даже "поврежденным") от URL-адреса, выводимого при первом преобразовании?

Ответ

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

Вопрос :

Должен ли я использовать атрибут DOE (disable-output-escaping="yes") для вывода требуемого URL?

Ответ

Нет, как показано в первом преобразовании.

Вопрос

Рекомендуется ли использовать атрибут DOE (disable-output-escaping="yes") для вывода требуемого URL?

Ответ

Нет, использование DOE является плохой практикой в ​​XSLT и обычно сигнализирует о том, что программист плохо разбирается в модели обработки XSLT. Кроме того, DOE - это только дополнительная функция XSLT 1.0, и возможно, что ваш процессор XSLT не поддерживает DOE, или даже если это так, у вас могут возникнуть проблемы при выполнении того же преобразования с другим процессором XSLT.

Вопрос

Я пришел из другой проблемы к вопросу, за который я наградил. Моя проблема: я пытаюсь сгенерировать этот метод onclick:

    <input type="submit" 
onClick="return confirm('are you sure?') && confirm('seriously?');" />

я могу сделать следующее: я могу поместить подтверждения в функцию ... но ее Дайте мне понять, что я не могу создать атрибут & inside! Решение я думаю, что этот вопрос решает мою проблему.

Ответ

На самом деле вы можете указать логическую операцию && внутри выражения JavaScript внутри атрибута, представив ее как &amp;&amp;

Вот полный пример , который может запустить каждый, как я делал в трех браузерах: Chrome, Firefox 41.1.01 и IE11:

HTML

<!DOCTYPE html> 

    <html> 
      <head> 
        <link rel="stylesheet" href="style.css"> 
        <script src="script.js"></script> 
      </head> 
      <body> 
        <h1>Hello Plunker!</h1> 
        <input type="submit" 
onClick="alert(confirm('are you sure?') &amp;&amp; confirm('seriously?'));" /> 
      </body> 
    </html>

JavaScript (script.js):

function confirm(message) { 
  alert(message); 
  return message === 'are you sure?'; 

}

Когда вы запустите это, вы сначала получите это предупреждение:

enter image description here

Затем, после нажатия кнопки OK, вы получите второе предупреждение:

enter image description here

И после нажатия OK вы, наконец, получите предупреждение о результате операции &&:

enter image description here

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

Например, если вы измените элемент <input> на этот:

<input type="submit" 
onClick="alert(confirm('really sure?') &amp;&amp; confirm('seriously?'));" /> 

Сначала вы получите это предупреждение:

enter image description here

И когда вы нажмете OK, вы сразу получите окончательный результат операции &&:

enter image description here

Второе предупреждение пропускается, поскольку 1-й операнд операции && был false, а JavaScript - ярлык &&, где 1-й операнд false.

Подводя итог :

Оператор && можно легко использовать внутри атрибута в HTML-документе, созданном XSLT, указав операнд && как &amp;&amp;

10 голосов
/ 16 сентября 2008

Вы выражаете URI в HTML или XHTML? например <tag attr="http://foo.bar/?key=value&amp;key2=value2&amp;..."/> Если это так, «&amp;» - это правильный способ выражения амперсанда в значении атрибута, даже если он выглядит иначе, чем желаемый литеральный URI. Браузеры будут декодировать "&amp;" и любую другую ссылку на символьную сущность перед их загрузкой или передачей во Flash. Для вставки литерала, одиночный "&" непосредственно в HTML или XHTML неверен.

Я также лично рекомендую больше узнать об XML, чтобы более четко обдумывать подобные вещи. Например, попробуйте использовать W3C DOM больше (не только для простого Javascript); даже если вы не используете его изо дня в день, изучение DOM помогло мне правильно подумать о древовидной структуре XML и о том, как правильно кодировать атрибуты и элементы.

6 голосов
/ 16 сентября 2008

Используйте disable-output-escaping="yes" в вашем value-of теге

4 голосов
/ 16 сентября 2008

Если вы пытаетесь создать XML-файл как выходной, вы захотите создать &amp; (так как & сам по себе является недопустимым XML). Если вы просто создаете строку, то вы должны установить режим вывода таблицы стилей на text, включив следующее как дочерний элемент xsl:stylesheet

<xsl:output method="text"/>

Это предотвратит экранирование таблицы стилей, и <xsl:value-of select="'&amp;'" /> должно выдать &.

4 голосов
/ 16 сентября 2008

Если вы создаете строку запроса как часть большего URL-адреса в атрибуте какого-либо другого тега (например, «встраивать»), тогда вы на самом деле хотите, чтобы символ & был экранирован как & amp ;. В то время как все браузеры выяснят, что вы имеете в виду, и выполните все правильно, если вы передадите сгенерированный документ в валидатор, это пометит значение атрибута «без экранирования &» в атрибуте.

3 голосов
/ 08 октября 2008

Если ваше преобразование испускает документ XML, вы не должны отключать экранирование выходных данных. Вы хотите, чтобы в выводе были экранированы символы , чтобы вы не испортили искаженный XML. Объект XML, с которым вы обрабатываете выходные данные (например, DOM), отменит для вас текст.

Если вы используете обработку строк вместо объекта XML для обработки выходных данных, у вас есть проблема. Но проблема не в вашем XSLT, а в решении использовать строковые манипуляции для обработки XML, что почти всегда плохо.

Если ваше преобразование испускает HTML или текст (и вы установили тип вывода для элемента <xsl:output>, верно?), Это другая история. Тогда уместно использовать disable-output-escaping='yes' на вашем <xsl:value-of> элементе.

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

1 голос
/ 16 февраля 2016

Просто замените & на

<![CDATA[&]]>

в данных. Пример: данные XML

<title>Empire <![CDATA[&]]> Burlesque</title>

XSLT-тег:

<xsl:value-of select="title" />

Выход: Империя и Бурлеск

1 голос
/ 03 июня 2014

Отключение экранирования вывода выполнит работу ...... так как этот атрибут поддерживается только для текста, вы также можете манипулировать шаблоном, например:

 <xsl:variable name="replaced">

    <xsl:call-template name='app'>
      <xsl:with-param name='name'/>       
    </xsl:call-template>
  </xsl:variable>


<xsl:value-of select="$replaced" disable-output-escaping="yes"/>

---> Обернул вызов шаблона в переменную и использовал disable-output-escaping = "yes" ..

0 голосов
/ 25 января 2019

org.apache.xalan.xslt.Process, версия 2.7.2 выводит на приведенную выше ссылку «Вот бегущая, короткая и полная демонстрация того, как создать такой URL»:

<?xml version="1.0" encoding="UTF-8"?>http://www.myUrl.com/?vA=a&amp;vX=x&amp;vY=y&amp;vZ=z11522

Объявление XML подавляется дополнительным omit-xml-declaration="yes", но, тем не менее, при выводе method="text" экранирование от амперсандов не оправдано.

...