Подтвердить что ты не робот

Ошибка парсера XML: сущность не определена

Я искал stackoverflow по этой проблеме и нашел несколько тем, но я чувствую, что на самом деле для меня нет надежного ответа.

У меня есть форма, которую пользователи представляют, и значение поля сохраняется в XML файле. XML задан для кодирования с помощью UTF-8.

Время от времени пользователь будет копировать/вставлять текст где-то и что когда я получаю "сущность, не определенную ошибку".

Я понимаю, что XML поддерживает только несколько сущностей, и все, что за ним не распознано, - следовательно, ошибка парсера.

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

  • Я могу найти и заменить все   и заменить их на   или фактическое пространство.
  • Я могу разместить этот код в разделе CDATA.
  • Я могу включить эти объекты в XML файл.

Что я делаю с XML файлом, так это то, что пользователь может вводить содержимое в форму, он хранится в XML файле, и этот контент затем отображается как XHTML на веб-странице (разбирается с SimpleXML).

Из трех параметров или любых других (-их) вариантов (-ов), о которых я не знаю, действительно лучший способ справиться с этими сущностями?

Спасибо, Райан

UPDATE

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

Некоторые текстовые поля, где простые текстовые поля, но мои текстовые поля были расширены с помощью TinyMCE. Оказывается, при внимательном рассмотрении, что предупреждения PHP всегда ссылаются на данные из расширенных текстовых областей TinyMCE. Позже я заметил на ПК, что все персонажи были вывезены (потому что они не могли их прочитать), но на MAC вы могли видеть квадраты квадратов, ссылающиеся на номер юникода этого символа. Причина, по которой он проявился в квадратах на MAC, в первую очередь, заключается в том, что я использовал utf8_encode для кодирования данных, которые не были в UTF, чтобы предотвратить другие ошибки синтаксического анализа (что также связано с TinyMCE).

Решение для всего этого было довольно простым:

Я добавил эту строку entity_encoding : "utf-8" в свой tinyMCE.init. Теперь все символы отображаются так, как они должны.

Я думаю, единственное, что я не понимаю, - это то, почему персонажи все еще появляются, когда помещаются в текстовые поля, потому что ничто не преобразует их в UTF, но с TinyMCE это проблема.

4b9b3361

Ответ 1

Я согласен, что это чисто проблема с кодировкой. В PHP я решил эту проблему:

  • Перед передачей html-фрагмента в конструктор SimpleXMLElement я декодировал его с помощью html_entity_decode.

  • Затем дополнительно закодировано с помощью utf8_encode().

$headerDoc = '<temp>' . utf8_encode(html_entity_decode($headerFragment)) . '</temp>'; 
$xmlHeader = new SimpleXMLElement($headerDoc);

Теперь приведенный выше код не выдает никакой ошибки undefined.

Ответ 2

Вы можете анализировать текст в формате HTML и повторно использовать его с соответствующими числовыми объектами (например: &nbsp;&#160;). В любом случае - просто использование неуправляемого пользовательского ввода - плохая идея.

Все числовые объекты разрешены в XML, только те, которые известны из HTML, не работают (за исключением &amp;, &quot;, &lt;, &gt;, &apos;).

В большинстве случаев вы можете просто записать фактический символ (&ouml;ö) в XML файл, поэтому вообще не нужно использовать ссылку на сущность. Если вы используете DOM API для управления вашим XML (и вы должны!), Это ваша самая безопасная ставка.

Наконец, это ленивое решение для разработчиков, вы можете создать разбитый XML файл (т.е. неправильно сформированный с ошибками объекта) и просто передать его tidy для необходимых исправлений. Это может работать или может потерпеть неудачу в зависимости от того, насколько нарушено все это. По моему опыту, аккуратность довольно умна, и позволяет вам уйти с большим количеством.

Ответ 3

1. Я могу найти и заменить все [ &nbsp;?] И поменять их на [&#160;?] Или фактическое пространство.

Это надежный метод, но для этого требуется, чтобы у вас была таблица всех объектов HTML (я предполагаю, что вставленный ввод поступает из HTML) и анализирует вложенный текст для ссылок на сущности.

2. Я могу разместить этот код в разделе CDATA.

Другими словами, отключить синтаксический анализ для всего раздела? Тогда вам придется разбирать его по-другому. Может работать.

3. Я могу включить эти объекты в XML файл.

Вы имеете в виду включать определения сущности? Я думаю, что это простой и надежный способ, если вы не возражаете, чтобы XML файл был немного больше. У вас может быть "включенный" файл (найти его в Интернете), который является внешним объектом, с которым вы ссылаетесь в верхней части основного файла XML.

Один недостаток заключается в том, что используемый вами парсер XML должен обрабатывать внешние объекты (которые не все парсеры должны делать). И он должен правильно разрешить (возможно относительный) URL-адрес внешнего объекта к чему-то доступному. Это не так уж плохо, но это может увеличить ограничения на ваши инструменты обработки.

4. Вы можете запретить не-XML в вставленном контенте. Помимо всего прочего, это будет запрещать ссылки на сущности, которые не предопределены в XML (5, упомянутые Томалаком) или определенные в самом содержимом. Однако это может нарушить требования приложения, если пользователи должны иметь возможность вставлять туда HTML.

5. Вы можете анализировать вставленный контент как HTML в дерево DOM, установив someDiv.innerHTML = thePastedContent; Другими словами, создайте div где-нибудь (возможно, display = none, за исключением отладки). Скажем, у вас есть переменная javascript myDiv, которая содержит этот элемент div, а другая переменная myField, которая содержит элемент, который является вашим текстовым полем ввода. Затем в javascript вы делаете

myDiv.innerHTML = myField.value;

который берет unparsed текст из myField, анализирует его в дереве HTML DOM и вставляет его в myDiv как содержимое HTML.

Затем вы должны использовать некоторый браузерный метод для сериализации (= "де-парсинга" ) дерева DOM в XML. См. Например этот вопрос. Затем вы отправляете результат на сервер как XML.

Если вы хотите сделать это исправление в браузере или на сервере (как предлагал @Hannes), это будет зависеть от размера данных, от того, насколько быстро ответ должен быть, насколько утончен ваш сервер и заботитесь ли вы о хакерах, отправляющих неправильно сформированный XML.

Ответ 4

Если вы хотите преобразовать все символы, это может вам помочь (я написал это некоторое время назад):

http://www.lautr.com/convert-all-applicable-characters-to-numeric-entities-for-use-in-xml

function _convertAlphaEntitysToNumericEntitys($entity) {
  return '&#'.ord(html_entity_decode($entity[0])).';';
}

$content = preg_replace_callback(
  '/&([\w\d]+);/i',
  '_convertAlphaEntitysToNumericEntitys',
  $content);

function _convertAsciOver127toNumericEntitys($entity) {
  if(($asciCode = ord($entity[0])) > 127)
    return '&#'.$asciCode.';';
  else
    return $entity[0];
}

$content = preg_replace_callback(
  '/[^\w\d ]/i',
  '_convertAsciOver127toNumericEntitys', $content);

Ответ 5

Этот вопрос является общей проблемой для любого языка, который анализирует XML или JSON (так, в основном, каждый язык).

Вышеупомянутые ответы для PHP, но решение Perl было бы таким же простым, как...

my $excluderegex =
    '^\n\x20-\x20' .   # Don't Encode Spaces
       '\x30-\x39' .   # Don't Encode Numbers
       '\x41-\x5a' .   # Don't Encode Capitalized Letters
       '\x61-\x7a' ;   # Don't Encode Lowercase Letters

    # in case anything is already encoded
$value = HTML::Entities::decode_entities($value);

    # encode properly to numeric
$value = HTML::Entities::encode_numeric($value, $excluderegex);