krpano | Символ & не работает в openurl() | xml parsing failed

krpano | Символ & не работает в openurl() | xml parsing failed

В чём суть проблемы?

Любой тур от krpano динамически генерирует при просмотре ссылки, вида:

https://example.com/pano/pano27/?startscene=0&startactions=lookat(89.65,37.67,97.63,0,1);

Стандарт URI говорит о том, что знак вопроса (?) символизирует начало запроса на сервер. То есть всё что следует справа от вопроса является парами «параметр/значение». Если на сервер нужно передать несколько параметров, то между ними устанавливается символ амперсанда (&).

В нашем случае startscene определяет сферическую панораму, а значение (0) указывает порядковый номер панорамы, которую нужно загрузить. Далее в запросе идёт тот самый злополучный знак амперсанда (&). После него идёт startactions который определяет координаты. Значение lookat(89.65,37.67,97.63,0,1) указывает точное направление взгляда в панораме.

Когда мы видим такой адрес в браузере — всё ок. Тур крутится, панаромы кликаются, переходы работают. Но как только мы хотим вручную видоизменить файл «tout.xml» и указать подобные ссылки — начинаются проблемы.

Проблема

Использование символа (&) вызывает ошибку синтаксического анализа файла «tour» с расширением «xml». Из-за этого тур не стартует на сайте и блокируется отображение содержимого тура. То есть когда хочется организовать переходы между двумя и более виртуальными турами на сайте (по логике работы самого же krpano), возникает проблема.

У нас есть необходимость использования функции openurl(). В эту функцию мы передаём два аргумента: url и target

URL — в одинарных кавычках указываем URL-адрес, который необходимо открыть

TARGET — указываем способ, которым мы будем открывать URL:

_blank — открыть URL-адрес в новом окне (по умолчанию)
_self — открыть URL-адрес в текущем фрейме в текущем окне
_parent — открыть URL-адрес в родительском элементе текущего кадра
_top — открыть URL-адрес во фрейме верхнего уровня в текущем окне

 

В убогой документации на официальном сайте написано (https://krpano.com/docu/actions/#expressions.strict):

Note — due of xml syntax limitations, the usage of the characters <, >, & might be not possible (e.g. inside xml attributes or inside xml elements without CDATA tag). Therefore it’s recommended to use the alternative syntax.

Примечание — из-за ограничений синтаксиса xml использование символов<,>, & может быть невозможно (например, внутри атрибутов xml или внутри элементов xml без тега CDATA). Поэтому рекомендуется использовать альтернативный синтаксис.

Какой альтернативный синтаксис?
Какой альтернативный синтаксис?

После этого хочется задать вопрос: Какой синтаксис нужно использовать? Где мне искать ответы? Я похож на программиста или что?

 

Если я создам горячую точку в таком виде:

<hotspot name="spot15" style="skin_hotspotstyle" ath="148.378" atv="4.066"
   onclick="openurl('https://example.com/pano75/?startscene=20&startactions=lookat(135.14,4.66,120,0,1)',_blank)"
   onhover="showtext('Переход в другой 3D тур')"/>

…то я получу FATAL ERROR:

FATAL ERROR krpano
FATAL ERROR krpano

Всё дело в амперсанде (&). Но как решить проблему? В интернете так много информации от разных авторов, но ни один мне не смог помочь с решением. В итоге пришлось разбираться самому. И тебе повезло, потому что я нашёл решение проблемы.

 

Решение проблемы

Чтобы функция нормально работала, нужно правильно экранировать символ амперсанда (&). Далее важная, но скучная информация с официального сайта стандарта XML.

Определение: ссылки на сущности и символы могут использоваться для экранирования левой угловой скобки, амперсанда и других разделителей. Для этого задается набор общих сущностей (amp, lt, gt, apos, quot). Также могут использоваться ссылки на числовые символы; они немедленно расширяются при распознавании и должны рассматриваться как символьные данные, поэтому ссылки на числовые символы «&#60; » и «&#38; » могут использоваться для экранирования < и &, когда они встречаются в символьных данных.

Все процессоры XML должны распознавать эти объекты независимо от того, объявлены они или нет. Для обеспечения взаимодействия в допустимых XML-документах эти сущности должны быть объявлены, как и любые другие, перед их использованием.

Если объекты lt или amp объявлены, они должны быть объявлены как внутренние объекты, замещающий текст которых является символьной ссылкой на соответствующий экранируемый символ (знак «меньше» или амперсанд); для этих сущностей требуется двойное экранирование, чтобы ссылки на них давали хорошо сформированный результат.

Если объявлены объекты gt, apos или quot, они должны быть объявлены как внутренние объекты, замещающий текст которых является одиночным экранируемым символом (или символьной ссылкой на этот символ; двойное экранирование здесь необязательно, но безвредно). Например:

<!ENTITY lt    "&#38;#60;">
<!ENTITY gt    "&#62;">
<!ENTITY amp   "&#38;#38;">
<!ENTITY apos  "&#39;">
<!ENTITY quot  "&#34;">
Варианты экранирования в XML
Варианты экранирования в XML

 

Правильный вариант написания ссылок на 3D туры krpano в функции openurl()

Находим амперсанд (&) и заменяем его на (&#38;)

<hotspot name="spot15" style="skin_hotspotstyle" ath="148.378" atv="4.066"
   onclick="openurl('https://example.com/pano75/?startscene=20&#38;startactions=lookat(135.14,4.66,120,0,1)',_blank)"
   onhover="showtext('Переход в другой 3D тур')"/>

 

Информационные ссылки

Стандарт «Extensible Markup Language (XML) 1.0 (Fifth Edition)» — https://www.w3.org/TR/xml/

Раздел «4.6 Predefined Entities» — https://www.w3.org/TR/xml/#sec-predefined-ent

Функция — https://krpano.com/docu/actions/#openurl

 

Поделись страницей. Расскажи обо мне.