Зафиксируйте уродливый XML в PHP прежде, чем обработать использование функции DOMDocument

Я должен загрузить XML-документ в PHP, который прибывает из внешнего источника. XML не объявляет, что кодирует и содержит запрещенные символы как &. Если я пытаюсь загрузить XML-документ непосредственно в браузере, я добираюсь, ошибки как "Недопустимый символ был найден в текстовом содержании" также при загрузке файла в PHP, как который я получаю много предупреждений: xmlParseEntityRef: no name in Entity и Input is not proper UTF-8, indicate encoding ! Bytes: 0x9C 0x31 0x21 0x3C.

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

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

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

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

Мой код в настоящее время похож:

  $feedURL = '3704017_14022010_050004.xml';
  $dom = new DOMDocument();
  $dom->load($feedURL);

Проблема кодирования показа XML-файла в качестве примера (нажимают для загрузки): feed.xml

XML в качестве примера, который содержит символы, которые не были преобразованы в объекты XML:




117387
Test
10544740
This & This
For one day only this is > than this.


8
задан Camsoft 17 February 2010 в 11:37
поделиться

1 ответ

Попробуйте использовать библиотеку Tidy, которую можно использовать для очистки плохого HTML и XML http://php.net/ manual / en / book.tidy.php

Чистое PHP-решение для исправления некоторого XML, например:

<?xml version="1.0"?>
<feed>
<RECORD>
<ID>117387</ID>
<ADVERTISERNAME>Test < texter</ADVERTISERNAME>
<AID>10544740</AID>
<NAME>This & This</NAME>
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION>
</RECORD>
</feed>

Будет примерно так:

  function cleanupXML($xml) {
    $xmlOut = '';
    $inTag = false;
    $xmlLen = strlen($xml);
    for($i=0; $i < $xmlLen; ++$i) {
        $char = $xml[$i];
        // $nextChar = $xml[$i+1];
        switch ($char) {
        case '<':
          if (!$inTag) {
              // Seek forward for the next tag boundry
              for($j = $i+1; $j < $xmlLen; ++$j) {
                 $nextChar = $xml[$j];
                 switch($nextChar) {
                 case '<':  // Means a < in text
                   $char = htmlentities($char);
                   break 2;
                 case '>':  // Means we are in a tag
                   $inTag = true;
                   break 2;
                 }
              }
          } else {
             $char = htmlentities($char);
          }
          break;
        case '>':
          if (!$inTag) {  // No need to seek ahead here
             $char = htmlentities($char);
          } else {
             $inTag = false;
          }
          break;
        default:
          if (!$inTag) {
             $char = htmlentities($char);
          }
          break;
        }
        $xmlOut .= $char;
    }
    return $xmlOut;
  }

Это простой конечный автомат, определяющий, находимся мы в теге или нет а если нет, то кодируйте текст с помощью htmlentities.

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

8
ответ дан 5 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

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