Я успешно смог опубликовать опубликованную страницу результатов в формате 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> <PubmedArticle> <MedlineCitation Status="Publisher" Owner="NLM"> <PMID Version="1">23314841</PMID> <DateCreated> <Year>2013</Year> <Month>1</Month> <Day>14</Day> </DateCreated> <Article PubModel="Print-Electronic"> <Journal> <ISSN IssnType="Electronic">1432-0932</ISSN> <JournalIssue CitedMedium="Internet"> <PubDate> <Year>2013</Year> <Month>Jan</Month> <Day>12</Day> </PubDate> ... (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 }
Объяснить:
<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='. Urlencode ('b & c'))) , Начиная с PHP 5.1.0 вам не нужно это делать, потому что PHP сделает это за вас.
simplexml_load_file