Невозможно получить xslt для вывода (&) даже после экранирования символа

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

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

13 ответов

Вы можете объединить disable-output-escaping с CDATA раздел. Попробуй это:

<xsl:text disable-output-escaping="yes"><![CDATA[&]]></xsl:text>

Я пытаюсь создать строку запроса переменных назначений, разделенных & символ (например: "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?');" />

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

Ответ

На самом деле, вы можете указать && Булева операция внутри выражения 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?'; 

}

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

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

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

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

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

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

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

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

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

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

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

Вы выражаете 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 и о том, как правильно кодировать атрибуты и элементы.

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

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

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

<xsl:output method="text"/>

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

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

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

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

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

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

 <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"..

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

<![CDATA[&]]>

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

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

Тег XSLT:

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

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

Вы должны заметить, что вы можете использовать disable-output-escaping внутри значения узла или строки / текста, например:

<xsl:value-of select="/node/here" disable-output-escaping="yes" />

или же

<xsl:value-of select="'&amp;'" disable-output-escaping="yes" />
<xsl:text disable-output-escaping="yes">Texas A&amp;M</xsl:text>

Обратите внимание на одинарные кавычки в xsl:value-of.

Однако вы не можете использовать отключение-выход-экранирование для атрибутов. Я знаю, что это полностью запутано, но так обстоит дело в XSLT 1.0. Таким образом, следующее не будет работать:

<xsl:value-of select="/node/here/@ttribute" disable-output-escaping="yes" />

Потому что в мелкий шрифт цитата:

Таким образом, было бы ошибкой отключать экранирование выхода для <xsl:value-of /> или же <xsl:text /> элемент, который используется для генерации строкового значения комментария, инструкции обработки или узла атрибута;

Акцент мой.

Взято с: http://www.w3.org/TR/xslt

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" выход из амперсанда не оправдан.

С использованием disable-output-escaping Атрибут (логическое), вероятно, самый простой способ сделать это. Обратите внимание, что вы можете использовать это не только на <xsl:value-of/> но и с <xsl:text>, который может быть чище, в зависимости от вашего конкретного случая.

Вот соответствующая часть спецификации: http://www.w3.org/TR/xslt

try:

Извините, если форматирование испортилось.

Другие вопросы по тегам