2010-02-14 4 views
7

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

Понятно, что 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:

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

«Как все остальные счастливые клиенты (?) Имеют дело с данными и почему я единственный несчастный парень» - вот вопрос, который я задал бы провайдеру. Можете ли вы предоставить (точный) примерный документ? – VolkerK

+0

Мне это было интересно.Я говорил с ними, и они сказали мне, что у них проблемы с качеством данных, и сказали контент-провайдерам разобраться. Я предполагаю, что другие клиенты нашли способ исправить фид XML, прежде чем пытались его обработать. Отсюда мой вопрос. – Camsoft

+0

@VolkerK Я загрузил подмножество всего XML-документа как полный XML, как более 42 000 строк. – Camsoft

ответ

8

Попробуйте использовать библиотеку 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.

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

+0

Мне не удалось заставить это работать с MAMP на моем Mac. Это действительно расстраивает. – Camsoft

+0

Там есть чистая библиотека PHP, подобная Tidy, называемая htmLawed [http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/]. Возможно, вам повезло больше. – Neel

+0

Это выглядит интересно, хотя, похоже, речь идет об исправлении ошибок XML. Фактические ошибки, которые я испытываю, связаны с смешанным кодированием содержимого и символов, которые не были преобразованы в объекты XML. – Camsoft

9

Чтобы решить эту проблему, установите DomDocument recover property в TRUE до загрузки XML-документа

$dom->recover = TRUE;

Попробуйте этот код:

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

Работал для меня, спасибо :) – Wiliam

+0

Работает с «Дополнительным содержанием в конце документа в Entity» Предупреждения, см. Http://eval.in/26395 – hakre

0

Если аккуратным расширение не вариант, вы можете рассмотреть htmlpurifier ,