Когда на CDATA против Escape & Vice Versa?
Я создаю документы XML со значениями, полученными из БД. Иногда из-за устаревшей реализации я отброшу значение, содержащее char, которое недействительно, если оно не экранировано надлежащим образом (например, например).
Итак, вопрос будет, должен ли я CDATA или Escape? Являются ли определенные ситуации более подходящими для одного и другого?
Примеры:
<Email>foo&[email protected]</Email>
Я бы наклонился к CDATA.
<Name>Bob & Tom</Name>
Я склоняюсь к побегу здесь.
Я хочу избегать слепого CDATA'а каждый раз, но с точки зрения производительности кажется, что это логичный выбор. Это будет всегда быстрее, чем поиск недопустимого char, и если он существует, то заверните.
Мысли?
Ответы
Ответ 1
CDATA в первую очередь полезен, ИМО, для чтения человеком. Что касается машины, то нет никакой разницы между CDATA и экранированным текстом, отличным от длины, в лучшем случае. Возможно, экранированная версия займет немного больше времени, но я скажу, возможно, потому что это не должно быть существенным фактором, если ваше приложение в основном связано с IO.
Возможно, люди читают XML? Если нет, просто дайте парсеру XML делать то, что он делает, и не беспокойтесь о CDATA и экранированном тексте. Если люди будут читать этот XML, возможно, CDATA может быть лучшим выбором.
Если у вас будет элемент XML, значение которого равно XML, то для этого случая лучше всего будет использовать CDATA.
Для получения дополнительной информации см., например, вопрос о часто задаваемых вопросах XML, Когда следует использовать отмеченный CDATA раздел?
Ответ 2
Я видел, как люди используют CDATA для вышеуказанного, что хорошо, и для обертывания вещей, которые не являются XML, например, например. JSON или CSS - и это лучшая причина для его использования. Проблема возникает, когда люди используют ее для цитирования разметки на основе элементов, такой как HTML, а затем происходит путаница.
Люди не ожидают
<![CDATA[<foo>bar</foo>]]>
чтобы быть идентичным
<foo>bar</foo>
в отношении систем XML.
См. RSS-суп-суп для примеров ужаса уровней эскалации.
Вы также должны быть уверены, что последовательность символов ']] > ' никогда не будет отображаться в ваших завернутых данных, поскольку это означает, что терминатор.
Таким образом, если читаемость не является первостепенной или вы не переносите неэлементную разметку, я рекомендую избегать CDATA.
Ответ 3
Оберните с CDATA в этих условиях: Если у вас есть сомнительные данные, и вы пытаетесь избежать этих Данные используются для отображения, потому что тогда это приложение также будет unescape. Повторяйте один и тот же элемент данных - большее количество парсинга и выхода повлияет на производительность.
Ответ 4
Я думаю, что нет никакой реальной разницы. Я предпочитаю использовать CDATA для всего, потому что мне не нужно заботиться о том, чтобы символы уходили, и единственное, что я должен позаботиться, это "]] > " в содержании, которое, возможно, разрешено, если вы разделите открытие CDATA и закрытие тегов на несколько фрагментов.
Пример (в PHP)
<?php
function getXMLContent($content)
{
if
(
(strpos($content, '<') !== false) ||
(strpos($content, '>') !== false) ||
(strpos($content, '&') !== false) ||
(strpos($content, '"') !== false) ||
(strpos($content, '\'') !== false)
)
{
// If value contains ']]>', we need to break it into multiple CDATA tags
return "<![CDATA[". str_replace(']]>', ']]]]><![CDATA[>', $content) ."]]>";
}
else
{
// Value does not contain any special characters which needs to be wrapped / encoded / escaped
return $content;
}
}
echo getXMLContent("Hello little world!");
echo PHP_EOL . PHP_EOL;
echo getXMLContent("This < is > a & hard \" test ' for ]]> XML!");
?>
Возвращает
Hello little world!
<![CDATA[This < is > a & hard " test ' for ]]]]><![CDATA[> XML!]]>
Если вы поместите это в структуру XML, как это:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test>
<![CDATA[This < is > a & hard " test ' for ]]]]><![CDATA[> XML!]]>
</test>
... сохраните его в файле (например, test.xml) и откройте его в браузере, вы увидите, что браузер (или любой другой XML-приложение/парсер) покажет вам правильную строку вывода:
This < is > a & hard " test ' for ]]> XML!
Ответ 5
Я думаю, что CDATA будет быстрее - он должен сканировать конечный символ, сделать копию от начала до конца и передать ее обратно - одну копию.
При чтении экранированных данных он должен использовать буфер, добавляемый к нему, когда он сканирует экранированные символы, а когда он заканчивается, скрывает буфер до строки и передает это обратно.
Таким образом, побег будет использовать больше памяти и должен будет сделать дополнительную копию.
Хотя вы, вероятно, заметите разницу в больших наборах данных и большом количестве транзакций. Поэтому, если его небольшие поля, не беспокойтесь об этом - используйте либо.