Как отобразить]] & gt; в CDATA [дубликат]

Компиляция программы на C ++ выполняется в несколько этапов, как указано в 2.2 (кредиты для Кейта Томпсона для ссылки) :

Превалирование среди правил синтаксиса

  1. Физические символы исходного файла сопоставляются в соответствии с реализацией в соответствии с базовым набором символов источника (ввод символов новой строки для индикаторов конца строки) при необходимости. [SNIP]
  2. Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, сплайсируя физические исходные строки для формирования логических строк источника. [SNIP]
  3. Исходный файл разбивается на токены предварительной обработки (2.5) и последовательности символов пробела (включая комментарии). [SNIP]
  4. Выполнены предпроцессорные директивы, макро-вызовы разворачиваются и выполняются операторные выражения _Pragma. [SNIP]
  5. Каждый элемент набора символов в символьном литерале или строковый литерал, а также каждая escape-последовательность и универсальное имя-символа в символьном литерале или не- -raw строковый литерал, преобразуется в соответствующий член набора символов выполнения; [SNIP]
  6. Соединительные маркеры литералов строки объединены.
  7. Символы пробела, разделяющие токены, уже не являются значимыми. Каждый токен предварительной обработки преобразуется в токен. (2.7). Результирующие маркеры синтаксически и семантически анализируются и переводятся как единица перевода. [SNIP]
  8. Устанавливаемые единицы перевода и единицы экземпляра объединяются следующим образом: [SNIP]
  9. Все ссылки на внешние сущности решена. Компоненты библиотеки связаны для удовлетворения внешних ссылок на объекты, не определенные в текущем переводе. Весь такой переводчик выводится в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения. (акцент мой)

[footnote] Реализации должны вести себя так, как если бы эти отдельные фазы происходили, хотя на практике различные фазы могли быть свернуты вместе.

Указанные ошибки возникают на этом последнем этапе компиляции, чаще всего называемом связыванием. Это в основном означает, что вы собрали кучу файлов реализации в объектные файлы или библиотеки, и теперь вы хотите заставить их работать вместе.

Скажите, что вы определили символ a в a.cpp. Теперь b.cpp объявил этот символ и использовал его. Перед связыванием он просто предполагает, что этот символ был определен где-то , но он пока не заботится о том, где. Фаза связывания отвечает за поиск символа и правильную привязку его к b.cpp (ну, собственно, к объекту или библиотеке, которая его использует).

Если вы используете Microsoft Visual Studio, вы будете см., что проекты генерируют файлы .lib. Они содержат таблицу экспортированных символов и таблицу импортированных символов. Импортированные символы разрешены против библиотек, на которые вы ссылаетесь, и экспортированные символы предоставляются для библиотек, которые используют этот .lib (если есть).

Подобные механизмы существуют для других компиляторов / платформ.

Общие сообщения об ошибках: error LNK2001, error LNK1120, error LNK2019 для Microsoft Visual Studio и undefined reference to symbolName для GCC.

Код:

struct X
{
   virtual void foo();
};
struct Y : X
{
   void foo() {}
};
struct A
{
   virtual ~A() = 0;
};
struct B: A
{
   virtual ~B(){}
};
extern int x;
void foo();
int main()
{
   x = 0;
   foo();
   Y y;
   B b;
}

генерирует следующие ошибки с GCC:

/home/AbiSfw/ccvvuHoX.o: In function `main':
prog.cpp:(.text+0x10): undefined reference to `x'
prog.cpp:(.text+0x19): undefined reference to `foo()'
prog.cpp:(.text+0x2d): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD0Ev[B::~B()]+0x12): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1Y[typeinfo for Y]+0x8): undefined reference to `typeinfo for X'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B]+0x8): undefined reference to `typeinfo for A'
collect2: ld returned 1 exit status

и аналогичные ошибки с Microsoft Visual Studio:

1>test2.obj : error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)
1>test2.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ)
1>...\test2.exe : fatal error LNK1120: 4 unresolved externals

. Общие причины включают в себя:

116
задан Aaron Digulla 3 September 2013 в 11:49
поделиться

10 ответов

Ясно, что этот вопрос носит чисто академический характер. К счастью, у него есть определенный ответ.

Вы не можете избежать окончания конца CDATA. Правило 20 производства XML спецификации совершенно ясно:

[20]    CData      ::=      (Char* - (Char* ']]>' Char*))

EDIT: Это правило продукта буквально означает «Раздел CData может содержать все, что вы хотите, а последовательность»]] > '. Никаких исключений. ".

EDIT2: тот же раздел также читает:

В разделе CDATA используется только строка CDEnd распознается как разметка, так что левые угловые скобки и амперсанды могут встречаться в их буквальной форме; им не нужно (и не может) сбежать с помощью «<» и «&». Секции CDATA не могут встраиваться.

Другими словами, невозможно использовать ссылку на объект, разметку или любую другую интерпретационную форму. Единственный проанализированный текст внутри секции CDATA - ]]>, и он завершает раздел.

Следовательно, невозможно выйти из ]]> в секции CDATA.

EDIT3 : тот же раздел также читает:

2.7 Разделы CDATA

[Определение: разделы CDATA могут возникать в любом случае, когда могут встречаться персональные данные; они используются для удаления блоков текста, содержащих символы, которые в противном случае были бы распознаны как разметка. Секции CDATA начинаются со строки «& lt;! [CDATA [" и заканчиваются строкой "]] & gt;":]

Тогда может быть раздел CDATA, где могут встречаться любые персональные данные , включая несколько смежных секций CDATA на одном участке CDATA. Это позволяет разделить токен ]]> и поместить две части его в соседние секции CDATA.

ex:

<![CDATA[Certain tokens like ]]> can be difficult and <invalid>]]> 

следует записать как

<![CDATA[Certain tokens like ]]]]><![CDATA[> can be difficult and <valid>]]> 
126
ответ дан John Flatness 25 August 2018 в 06:30
поделиться

Более чистый способ в PHP:

   function safeCData($string)
   {
      return '<![CDATA[' . str_replace(']]>', ']]]]><![CDATA[>', $string) . ']]>';
   }

Не забудьте использовать многобайтовое str_replace, если необходимо (не latin1 $string):

   function mb_str_replace($search, $replace, $subject, &$count = 0)
   {
      if (!is_array($subject))
      {
         $searches = is_array($search) ? array_values($search) : array ($search);
         $replacements = is_array($replace) ? array_values($replace) : array ($replace);
         $replacements = array_pad($replacements, count($searches), '');
         foreach ($searches as $key => $search)
         {
            $parts = mb_split(preg_quote($search), $subject);
            $count += count($parts) - 1;
            $subject = implode($replacements[$key], $parts);
         }
      }
      else
      {
         foreach ($subject as $key => $value)
         {
            $subject[$key] = mb_str_replace($search, $replace, $value, $count);
         }
      }
      return $subject;
   }
1
ответ дан Alain Tiemblo 25 August 2018 в 06:30
поделиться

См. эту структуру:

<![CDATA[
   <![CDATA[
      <div>Hello World</div>
   ]]]]><![CDATA[>
]]>

Для внутреннего тега (ов) CDATA вы должны закрыть ]]]]><![CDATA[> вместо ]]>. Просто как это.

0
ответ дан Chad Kuehn 25 August 2018 в 06:30
поделиться

Вы не избегаете ]]>, но вы выйдете из > после ]], вставив ]]><![CDATA[ перед >, подумайте об этом точно так же, как \ в C / Java / PHP / Perl string, но нужно только до > и после ]].

BTW,

Ответ S.Lott такой же, как и этот, только что сформулированный по-разному.

15
ответ дан Jason Pyeron 25 August 2018 в 06:30
поделиться

Другим решением является замена ]]> на ]]]><![CDATA[]>.

0
ответ дан mik 25 August 2018 в 06:30
поделиться
[Д0] S. Ответ Lott прав: вы не кодируете конечный тег, вы разбиваете его на несколько разделов CDATA.

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

Но в большинстве случаев вы не столкнетесь с этим, и вот почему: если вы хотите сохранить (скажем) текст XML-документа в качестве содержимого XML, вы, вероятно, используете метод DOM, например:

XmlElement elm = doc.CreateElement("foo");
elm.InnerText = "<[CDATA[[Is this a problem?]]>";

И DOM вполне разумно избегает & lt; и>, что означает, что вы случайно не ввели раздел CDATA в свой документ.

О, и это интересно:

XmlDocument doc = new XmlDocument();

XmlElement elm = doc.CreateElement("doc");
doc.AppendChild(elm);

string data = "<![[CDATA[This is an embedded CDATA section]]>";
XmlCDataSection cdata = doc.CreateCDataSection(data);
elm.AppendChild(cdata);

Это, вероятно, идеология .NET DOM, но это не вызывает исключения. Исключение выбрано здесь:

Console.Write(doc.OuterXml);

Я бы предположил, что то, что происходит под капотом, заключается в том, что XmlDocument использует XmlWriter для вывода своего результата, а XmlWriter проверяет корректность при записи.

7
ответ дан Robert Rossney 25 August 2018 в 06:30
поделиться

Вы должны разбить свои данные на куски, чтобы скрыть ]]>.

Вот что:

<![CDATA[]]]]><![CDATA[>]]>

Первый <![CDATA[]]]]> имеет ]]. Второй <![CDATA[>]]> имеет >.

161
ответ дан S.Lott 25 August 2018 в 06:30
поделиться

Вот еще один случай, когда ]]> необходимо экранировать. Предположим, нам нужно сохранить полностью корректный HTML-документ внутри блока CDATA XML-документа, а источник HTML имеет собственный CDATA-блок. Например:

<htmlSource><![CDATA[ 
    ... html ...
    <script type="text/javascript">
        /* <![CDATA[ */
        -- some working javascript --
        /* ]]> */
    </script>
    ... html ...
]]></htmlSource>

прокомментированный суффикс CDATA необходимо изменить на:

        /* ]]]]><![CDATA[> *//

, поскольку синтаксический анализатор XML не будет знать, как обрабатывать блоки комментариев javascript

3
ответ дан Shawn Becker 25 August 2018 в 06:30
поделиться

просто замените ]]> на ]]]]><![CDATA[>

5
ответ дан Thomas Grainger 25 August 2018 в 06:30
поделиться

В PHP: '<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'

1
ответ дан user2194495 25 August 2018 в 06:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: