Ошибка PHP Simplexml_Load_File

Я успешно смог опубликовать опубликованную страницу результатов в формате xml и записать содержимое в локальный файл «Publications.xml». Проблема в том, что когда я использую simplexml_load_file («Publications.xml»), он терпит неудачу. Невозможно понять, почему.

<?php $feed = 'http://www.ncbi.nlm.nih.gov/pubmed?term=carl&sort=pubdate&report=xml'; $local = 'Publications.xml'; $curtime = time(); $filemodtime; if( (!file_exists($local)) || (time() - filemtime($local)) > 86400 ) { $contents = file_get_contents($feed); $fp = fopen($local,"w"); fwrite($fp, $contents); fclose($fp); } $xml = simplexml_load_file($local) or ("Can't"); ?> 

На последней, но второй строке синтаксический анализатор терпит неудачу, и я получаю сообщение «Can not». Я дважды проверил xml-файл и, похоже, был в хорошей форме.

Если кто-нибудь может сообщить мне о любых обходных решениях для этого, я буду очень благодарен. Вот копия xml-файла, который скрипт PHP выше пытается прочитать ( http://pastebin.com/U0fEKmZL ):

 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <pre> &lt;PubmedArticle&gt; &lt;MedlineCitation Status="Publisher" Owner="NLM"&gt; &lt;PMID Version="1"&gt;23314841&lt;/PMID&gt; &lt;DateCreated&gt; &lt;Year&gt;2013&lt;/Year&gt; &lt;Month&gt;1&lt;/Month&gt; &lt;Day&gt;14&lt;/Day&gt; &lt;/DateCreated&gt; &lt;Article PubModel="Print-Electronic"&gt; &lt;Journal&gt; &lt;ISSN IssnType="Electronic"&gt;1432-0932&lt;/ISSN&gt; &lt;JournalIssue CitedMedium="Internet"&gt; &lt;PubDate&gt; &lt;Year&gt;2013&lt;/Year&gt; &lt;Month&gt;Jan&lt;/Month&gt; &lt;Day&gt;12&lt;/Day&gt; &lt;/PubDate&gt; ... (too long, see link) 

По какой-то причине опубликованный сервер возвращает весь XML-файл в виде HTML-файла с одним <pre> содержащим XML. Он также содержит несколько фрагментов XML (есть несколько элементов <PubmedArticle> и вокруг них нет контейнера). Очевидно, что это предназначено для обработки каким-то дурацким пользовательским кодом.

Вы можете «развернуть» XML, дважды позвонив SimpleXML, например:

 $outer_xml = simplexml_load_file($local); $inner_xml = simplexml_load_string('<dummyContainer>' . (string)$outer_xml . '</dummyContainer>'); foreach ( $inner_xml->PubmedArticle as $article ) { // etc } 

Объяснить:

  • внешний «XML-документ» – это HTML, который имеет один внешний элемент <pre>
  • листинг, который для строки (который я сделал явно с (string) для ясности и хорошей привычки), предоставит вам содержимое этого <pre> , то есть все элементы <PubmedArticle>
  • завершение того, что содержимое <dummyElement> предоставит вам действительный XML-документ, причем каждый из элементов <dummyElement> будет представлять собой <PubmedArticle> элемент верхнего уровня в документе

Попробуйте urlencoding.

Заметка:

Libxml 2 unescapes URI, поэтому, если вы хотите передать, например, b & c как параметр URI a , вы должны вызвать simplexml_load_file (rawurlencode ('http://example.com/?a=&apos;. Urlencode ('b & c'))) , Начиная с PHP 5.1.0 вам не нужно это делать, потому что PHP сделает это за вас.

simplexml_load_file