Когда CDATA против Escape и наоборот? - PullRequest
13 голосов
/ 09 июня 2009

Я создаю XML-документы со значениями, извлеченными из БД. Иногда из-за унаследованной реализации я извлекаю значение, содержащее символ, недопустимый при неправильном экранировании (& например).

Таким образом, возникает вопрос, мне CDATA или Escape? Являются ли определенные ситуации более подходящими для одного против другого?

Примеры:

<Email>foo&bar@domain.com</Email>

Я бы склонялся здесь к CDATA.

<Name>Bob & Tom</Name>

Я бы хотел сбежать отсюда.

Я хочу избегать вслепую CDATA'ов каждый раз, но с точки зрения производительности кажется, что это логичный выбор. Это всегда будет быстрее, чем поиск недопустимого символа, и, если он существует, оберните.

Мысли

Ответы [ 5 ]

18 голосов
/ 09 июня 2009

CDATA в первую очередь полезен, IMO, для удобства чтения. Что касается машины, то между CDATA и экранированным текстом нет никакой разницы, кроме длины. Возможно, обработанная версия займет немного больше времени для обработки, но я говорю , возможно , потому что это не должно быть существенным фактором, если ваше приложение в основном связано с IO.

Люди могут читать XML? Если нет, просто позвольте анализатору XML делать то, что он делает, и не беспокойтесь о CDATA против экранированного текста. Если люди будут читать этот XML, то, возможно, CDATA может быть лучшим выбором.

Если у вас будет элемент XML со значением XML, то для этого случая CDATA может быть лучшим выбором.

Для получения дополнительной информации см., Например, вопрос «Часто задаваемые вопросы по XML», Когда мне следует использовать раздел с метками CDATA?

5 голосов
/ 09 июня 2009

Я видел, как люди используют CDATA для вышеупомянутого, который в порядке, и для упаковки вещей, которые не являются XML - такими как, например, JSON или CSS - и это лучшая причина для его использования. Проблема возникает, когда люди используют ее для цитирования элементной разметки, такой как HTML, и тогда возникает путаница.

Люди не ожидают

<![CDATA[<foo>bar</foo>]]>

должно быть идентично

&lt;foo&gt;bar&lt;/foo&gt;

в отношении систем XML.

См. RSS-тег супа для примеров ужаса побега уровней.

Вы также должны быть уверены, что последовательность символов ']]>' никогда не появится в ваших упакованных данных, поскольку это терминатор.

Так что, если удобочитаемость не имеет первостепенного значения или вы не заключаете неэлементную разметку, я рекомендую избегать CDATA.

1 голос
/ 23 октября 2015

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

?>

Returns

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!
0 голосов
/ 06 декабря 2016

Я думаю, что CDATA будет быстрее - он должен сканировать конечный символ, сделать копию от начала до конца и передать ее обратно - одну копию. При чтении экранированных данных он должен использовать буфер, добавлять к нему, когда он сканирует экранированные символы, и когда он закончится, конвертировать буфер в строку и передавать его обратно. Таким образом, побег будет использовать больше памяти и придется делать дополнительную копию. Хотя вы, вероятно, заметите только разницу в больших наборах данных и большом количестве транзакций. Так что, если это небольшие поля, не беспокойтесь об этом - используйте либо.

0 голосов
/ 25 сентября 2013

Обтекание CDATA в следующих условиях: Если у вас есть недостоверные данные, и вы хотите избежать этих Данные используются для отображения, потому что тогда это приложение также будет удалено. Повторно экранируйте один и тот же элемент данных - большее количество анализа и экранирования повлияет на производительность.

...