Когда лучше CDATA против Escape и наоборот?

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

Возникает вопрос: что делать: CDATA или Escape? Какие ситуации больше подходят для одного по сравнению с другим?

Примеры:

<Email>foo&[email protected]</Email>

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

<Name>Bob & Tom</Name>

Я склоняюсь к тому, чтобы сбежать отсюда.

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

Мысли?


person Carlos S    schedule 08.06.2009    source источник


Ответы (5)


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

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

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

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

person Eddie    schedule 09.06.2009
comment
CDATA также более удобен для сети для больших строк, которые необходимо экранировать, поэтому IMO его следует использовать в большинстве случаев, когда файл XML будет передаваться по сети. - person A.M.K; 11.03.2014

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

Люди не ждут

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

быть идентичным

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

что касается систем XML.

См. «Суп с тегами RSS», чтобы увидеть, как ужасно убегать с уровней.

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

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

person dajobe    schedule 09.06.2009

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

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

person santony    schedule 25.09.2013

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

person EarlB    schedule 06.12.2016