Невозможно получить xslt для вывода (&) даже после экранирования символа
Я пытаюсь создать строку запроса переменных назначений, разделенных &
символ (например: "var1=x&var2=y&..."
). Я планирую передать эту строку во встроенный флэш-файл.
У меня проблемы с получением &
символ для отображения в XSLT. Если я просто наберу &
без тегов существует проблема с отображением документа XSLT. Если я наберу &
без каких-либо тегов, то результат документа &
без изменений. Если я наберу <xsl:value-of select="&" />
или же <xsl:value-of select="&" />
Я также получаю ошибку. Это возможно? Примечание: я также пытался &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&vX=', $vX, '&vY=', $vY, '&vZ=', $vZ)"/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к любому исходному XML-документу (игнорируется):
<t/>
желаемый, правильный результат получается:
http://www.myUrl.com/?vA=a&vX=x&vY=y&vZ=z
Что касается других вопросов, поднятых в вопросе:
Если я наберу
&
без каких-либо тегов, то результат документа&
без изменений.
Вышеприведенное утверждение просто не соответствует действительности... Просто запустите приведенное выше преобразование и посмотрите на результат.
Что на самом деле происходит:
Результат, который вы видите, абсолютно верен, однако ваш метод вывода html
или же xml
(значение по умолчанию для method=
), поэтому сериализатор процессора XSLT должен представлять правильный результат - строку http://www.myUrl.com/?vA=a&vX=x&vY=y&vZ=z
- как (часть) текстового узла в правильно сформированном документе XML или в дереве HTML.
По определению в правильно сформированном XML-документе буквальный амперсанд должен экранироваться символьной ссылкой, такой как встроенный &
или же &
, или же &
Помните: строка, представленная как (часть) текстового узла 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&vX=', $vX, '&vY=', $vY, '&vZ=', $vZ)"/>
</t>
</xsl:template>
</xsl:stylesheet>
И результат:
<t>http://www.myUrl.com/?vA=a&vX=x&vY=y&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 внутри атрибута, представляя его как &&
Вот полный пример того, что каждый может работать, как я делал в трех браузерах: 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?') && 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?') && confirm('seriously?'));" />
Сначала вы получите это предупреждение:
И когда вы нажимаете OK
, вы сразу получите окончательный результат &&
операция:
Второе предупреждение пропускается, потому что 1-й операнд &&
операция была false
и JavaScript сокращает &&
где 1-й операнд false
,
Подводя итог:
Это легко использовать &&
оператор внутри атрибута в HTML-документе, созданном XSLT, указав &&
операнд как &&
Вы выражаете URI в HTML или XHTML? например <tag attr="http://foo.bar/?key=value&key2=value2&..."/>
Если так, "&
"это правильный способ выражения амперсанда в значении атрибута, даже если он выглядит не так, как вы хотите буквальный URI. Браузеры будут декодировать"&
"и любые другие ссылки на сущности символов перед их загрузкой или передачей во Flash. Чтобы вставить литерал, одинокий"&
"прямо в HTML или XHTML неверно.
Я также лично рекомендую больше узнать об XML, чтобы более четко обдумывать подобные вещи. Например, попробуйте использовать W3C DOM больше (не только для простого Javascript); даже если вы не используете его изо дня в день, изучение DOM помогло мне правильно подумать о древовидной структуре XML и о том, как правильно кодировать атрибуты и элементы.
Использование disable-output-escaping="yes"
в вашем value-of
тег
Если вы создаете строку запроса как часть более крупного URL-адреса в атрибуте какого-либо другого тега (например, "встраивать"), то вы на самом деле хотите, чтобы символ & был экранирован как & amp;. Хотя все браузеры выяснят, что вы имеете в виду, и выполните правильные действия, если вы передадите сгенерированный документ в валидатор, это пометит значение атрибута "не экранированный символ &".
Если вы пытаетесь создать XML-файл в качестве вывода, вы захотите создать &
(как &
сам по себе является недействительным XML). Если вы просто создаете строку, вы должны установить режим вывода таблицы стилей на text
включив следующее как дитя xsl:stylesheet
<xsl:output method="text"/>
Это предотвратит экранирование таблиц стилей и <xsl:value-of select="'&'" />
должен производить &
,
Если ваше преобразование испускает документ 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="'&'" disable-output-escaping="yes" />
<xsl:text disable-output-escaping="yes">Texas A&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&vX=x&vY=y&vZ=z11522
Объявление XML подавляется дополнительным omit-xml-declaration="yes"
, но с выходом method="text"
выход из амперсанда не оправдан.
С использованием disable-output-escaping
Атрибут (логическое), вероятно, самый простой способ сделать это. Обратите внимание, что вы можете использовать это не только на <xsl:value-of/>
но и с <xsl:text>
, который может быть чище, в зависимости от вашего конкретного случая.
Вот соответствующая часть спецификации: http://www.w3.org/TR/xslt