it-swarm-ru.tech

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

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

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

19
Bill

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

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

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

12
Dimitre Novatchev

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

10
user4010

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

6
Thunder3

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

4
rjray

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

<xsl:output method="text"/>

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

4
ashirley

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

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

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

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

3
Robert Rossney

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

<![CDATA[&]]>

в данных . EX: XML данных

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

Тег XSLT:

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

Результат: Империя и Бурлеск

1
Ram

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

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

1
Taran

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

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

0
tomasr

Следует отметить, что вы можете использовать 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" />

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

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

выделение мое.

Взято из: http://www.w3.org/TR/xslt#disable-output-escaping

0
Nika

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

0
Peter Dolland