Мне было интересно, есть ли способ избежать конечного токена CDATA ( ]]>
) в разделе CDATA в документе xml. Или, в более общем смысле, если есть какая-то escape-последовательность для использования в CDATA (но если она существует, я думаю, что, в любом случае, имеет смысл только избегать токенов начала или конца).
В принципе, можете ли вы иметь начальный или конечный токен, встроенный в CDATA, и указать парсеру, чтобы он не интерпретировал его, а обрабатывал его как просто другую последовательность символов.
Возможно, вам следует просто провести рефакторинг своей xml-структуры или кода, если вы обнаружите, что пытаетесь это сделать, но хотя я работал с xml ежедневно в течение последних 3 лет или около того, и у меня никогда не было этой проблемы, Мне было интересно, возможно ли это. Просто из любопытства.
Редактировать:
Кроме использования кодировки html ...
>
как>
в CData, чтобы гарантировать, что встроенное]]>
не будет проанализировано как CDEnd. Это просто означает, что это неожиданно, и это&
должно быть ПЕРВОЕ закодировано,&
чтобы данные можно было правильно декодировать. Пользователи документа должны знать, как декодировать эти CData. Это не является чем-то необычным, поскольку часть цели CData состоит в том, чтобы содержать контент, с которым конкретный потребитель понимает, как обращаться. Нельзя ожидать, что такая CData будет правильно интерпретирована любым универсальным потребителем.CDATA
был разработан, чтобы разрешить все : они используются для экранирования блоков текста, содержащих символы, которые в противном случае были бы распознаны как разметка. Это также подразумевает,CDATA
поскольку это также разметка. Но на самом деле вам не нужно двойное кодирование, о котором я говорил.]]>
является приемлемым средством кодированияCDEnd
вCDATA
.Ответы:
Ясно, что это чисто академический вопрос. К счастью, на него есть однозначный ответ.
Вы не можете избежать конечной последовательности CDATA. Правило производства 20 спецификации XML довольно ясно:
РЕДАКТИРОВАТЬ: Это правило продукта буквально означает «Раздел CData может содержать все, что вы хотите, НО последовательность ']]>'. Без исключения.».
EDIT2: в этом же разделе также говорится:
Другими словами, невозможно использовать ссылку на сущность, разметку или любую другую форму интерпретируемого синтаксиса. Единственный анализируемый текст внутри раздела CDATA - это
]]>
, и он завершает раздел.Следовательно, невозможно выйти
]]>
из раздела CDATA.EDIT3: в том же разделе также говорится:
Затем может быть раздел CDATA везде, где могут встречаться символьные данные, включая несколько смежных разделов CDATA вместо одного раздела CDATA. Это позволяет разделить
]]>
токен и поместить две его части в соседние разделы CDATA.например:
следует записать как
источник
<script>/*<![CDATA[*/javascript goes here/*]]>*/</script>
и мой javascript включает именно эту последовательность! Мне нравится идея разделения на несколько разделов CDATA ...[[United States dollar|US$]]>100 million (2013)
который был переведен[[United States dollar|US$]]>100 million (2013)
читателем, а писатель решил использовать CDATA для экранирования текста и не смог.Вы должны разбить свои данные на части, чтобы скрыть расширение
]]>
.Вот и все:
<![CDATA[]]]]><![CDATA[>]]>
Первый
<![CDATA[]]]]>
имеет расширение]]
. Второй<![CDATA[>]]>
имеет расширение>
.источник
]]>
as]]]]><![CDATA[>
. В 5 раз длиннее ... вау. Но тогда это необычная последовательность.Вы не избегаете,
]]>
но вы избегаете>
после]]
, вставляя]]><![CDATA[
перед>
, думайте об этом так же, как\
в строке C / Java / PHP / Perl, но необходимо только до>
и после]]
.КСТАТИ,
Ответ С.Лотта такой же, только в другой формулировке.
источник
]]]]><![CDATA[>
это не какая-то магическая последовательность для]]>
.]]]]>
содержит]]
символы в качестве данных и]]>
завершает текущий раздел CDATA.<![CDATA[>
запускает новый раздел CDATA и помещает>
в него. На самом деле это два разных элемента, и при работе с парсером DOM они будут обрабатываться по-разному. Вы должны знать об этом. Этот способ выполнения аналогичен]]]><![CDATA[]>
, за исключением того, что он вводит]
первый и]>
второй CDATA. Разница остается.Ответ С. Лотта правильный: вы не кодируете конечный тег, вы разбиваете его на несколько разделов CDATA.
Как решить эту проблему в реальном мире: используя редактор XML для создания XML-документа, который будет загружен в систему управления контентом, попробуйте написать статью о разделах CDATA. Ваш обычный трюк с встраиванием примеров кода в раздел CDATA здесь не поможет. Вы можете себе представить, как я это узнал.
Но в большинстве случаев вы не столкнетесь с этим, и вот почему: если вы хотите сохранить (скажем) текст XML-документа как содержимое элемента XML, вы, вероятно, будете использовать метод DOM, например:
И DOM вполне разумно избегает <и>, что означает, что вы случайно не встроили раздел CDATA в свой документ.
Ах да, это интересно:
Вероятно, это идеосинкразия .NET DOM, но это не вызывает исключения. Здесь возникает исключение:
Я предполагаю, что под капотом происходит то, что XmlDocument использует XmlWriter для вывода, а XmlWriter проверяет правильность формата при записи.
источник
просто замените
]]>
на]]]]><![CDATA[>
источник
Вот еще один случай, от которого
]]>
нужно убежать. Предположим, нам нужно сохранить совершенно корректный HTML-документ внутри блока CDATA XML-документа, а источник HTML имеет собственный блок CDATA. Например:закомментированный суффикс CDATA необходимо изменить на:
поскольку синтаксический анализатор XML не будет знать, как обрабатывать блоки комментариев javascript
источник
]]>
на]]]]><![CDATA[>
все еще применяется здесь. То, что это JavaScript или прокомментированный, не имеет значения.В PHP:
'<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'
источник
Более чистый способ в PHP:
Не забудьте при необходимости использовать многобайтовый str_replace (не latin1
$string
):источник
Я не думаю, что прерывание CDATA - хороший выход. Вот моя альтернатива ...
Используйте
]
для escape-последовательности, за которой следует шестнадцатеричное значение вашего символа. Как в&#xhhhh;
=>]<unicode value>;
Таким образом, если вы попытаетесь записать
]]>
код, fn выдаст,]005D;]005D;]003E;
что нормально для CDATA.Это лучше, чем экранирование по имени сущности, потому что они не декодируются каждый раз в вашем приложении, и у вас могут быть разные приоритеты для экранирования сущностей с амперсандом по сравнению с экранированием некоторых других символов / последовательностей. В результате у вас больше контроля над содержимым CDATA.
источник
См. Эту структуру:
Для внутреннего тега (ов) CDATA вы должны закрыть
]]]]><![CDATA[>
вместо]]>
. Просто как тот.источник