When attempting to create a new instance of SimpleXMLElement from a URL, I get the error Uncaught exception 'Exception' with message 'String could not be parsed as XML'.
Details:
$feed_url = 'https://www.ua.edu/news/feed/';
$the_feed = new SimpleXMLElement( $feed_url, LIBXML_NOCDATA, true );
When executing the code above, the error appears on both the Stage and Prod environments but not in Dev. I have compared the xml related settings between the Stage and Dev environments and only slight version differences exist (Dev is a SLIGHTLY older version of PHP than Stage/Prod).
$feed_url = 'http://hiphopdx.com/rss/news.xml';
$the_feed = new SimpleXMLElement( $feed_url, LIBXML_NOCDATA, true );
In Stage (Can't test this part in Prod), I changed the $feed_url variable to another feed's URL. Everything works as expected. A SimpleXMLElement object is created and can be dumped to the screen.
I have no clue how to proceed to correct this. Any help is much appreciated.
I checked all of the server settings that were referenced in similar questions and they were all properly set. I never did figure out why it wasn't pulling the XML from the file. The solution that I ended up using was to use curl to get the XML from the URL and SimpleXMLELEMENT to handle the raw XML.
function produce_XML_object_tree($raw_XML) {
libxml_use_internal_errors(true);
try {
$xmlTree = new SimpleXMLElement($raw_XML);
} catch (Exception $e) {
// Something went wrong.
$error_message = 'SimpleXMLElement threw an exception.';
foreach(libxml_get_errors() as $error_line) {
$error_message .= "\t" . $error_line->message;
}
trigger_error($error_message);
return false;
}
return $xmlTree;
}
$feed_url = 'http://feed.url';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);
$the_feed = produce_XML_object_tree($xml)
Related
[![enter image description here][1]][1]I am trying to get the some tag value but it's showing some error.
Below is the code, please suggest some solution.
This is the method i used for httpGet request.
function httpGet($result15)
{
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$result15);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
$result15= httpGet("https://www.googleapis.com/customsearch/v1?key=API_KEY&cx=003255er&q=cancer&num=1&alt=atom");//new cse
echo $result15;
$xml = new DOMDocument();
$xml->loadXML($result15);
foreach( $xml->entry as $entry )
{
echo "URL=".(string)$entry->id.PHP_EOL;
echo "Summary=".(string)$entry->summary.PHP_EOL;
}
You might find the curl request is failing. You need to do a couple of things...
function httpGet($result15)
{
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$result15);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Add this
$output=curl_exec($ch);
// If this fails, output error.
if ($output === FALSE) {
echo curl_error($ch);
// Not sure what you want to do, but 'exit' will work for now
exit();
}
curl_close($ch);
return $output;
}
This will display an error if the curl request fails. You will need to decide how your going to cope with this. You could return false, and then in your code further down, check this before trying to load it as XML. The code above just stops on errors.
Your next piece of code seems to mix SimpleXML and DOMDocument, you can use SimpleXML if the document structure is fairly straight forward...
$xml = simplexml_load_string($result15);
foreach( $xml->entry as $entry )
{
I am trying to use the currentcy exchange rate feeds of the European Central Bank (ECB)
http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml
They have provided documentation on how to parse the xml but none of the options works for me: I checked that allow_url_fopen=On is set.
http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html
For instance, I used but it doesn't echo anything and it seems the $XML object is always empty.
<?php
//This is aPHP(5)script example on how eurofxref-daily.xml can be parsed
//Read eurofxref-daily.xml file in memory
//For the next command you will need the config option allow_url_fopen=On (default)
$XML=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
//the file is updated daily between 2.15 p.m. and 3.00 p.m. CET
foreach($XML->Cube->Cube->Cube as $rate){
//Output the value of 1EUR for a currency code
echo '1€='.$rate["rate"].' '.$rate["currency"].'<br/>';
//--------------------------------------------------
//Here you can add your code for inserting
//$rate["rate"] and $rate["currency"] into your database
//--------------------------------------------------
}
?>
Update:
As I am behind proxy at my test environment, I tried this but still I don't get to read the XML:
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_close ($ch);
return curl_exec($ch); }
$address = urlencode($address);
$data = curl("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml");
$XML = simplexml_load_file($data);
var_dump($XML); -> returns boolean false
Please help me. Thanks!
I didn't find any relevant settings in php.ini. Check with phpinfo() if you have SimpleXML support and cURLsupport enabled. (You should have them both and especially SimpleXML since you're using it and it returns false, it doesn't complain about missing function.)
Proxy might be an issue here. See this and this answer. Using cURL could be an answer to your problem.
Here's one alternative foud here.
$url = file_get_contents('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
$xml = new SimpleXMLElement($url) ;
//file put contents - same as fopen, wrote and close
//need to output "asXML" - simple xml returns an object based upon the raw xml
file_put_contents(dirname(__FILE__)."/loc.xml", $xml->asXML());
foreach($xml->Cube->Cube->Cube as $rate){
echo '1€='.$rate["rate"].' '.$rate["currency"].'<br/>';
}
This solution works for me:
$data = [];
$url = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";
$xmlRaw = file_get_contents($url);
$doc = new DOMDocument();
$doc->preserveWhiteSpace = FALSE;
$doc->loadXML($xmlRaw);
$node1 = $doc->getElementsByTagName('Cube')->item(0);
foreach ($node1->childNodes as $node2) {
$value = [];
foreach ($node2->childNodes as $node3) {
$value['date'] = $node2->getAttribute('time');
$value['currency'] = $node3->getAttribute('currency');
$value['rate'] = $node3->getAttribute('rate');
$data[] = $value;
unset($value);
}
}
echo "<pre"> . print_r($data) . "</pre>";
i just want to get the name of 'channel' tag i.e. CHANNEL...the script works fine when i use it to parse the rss from Google..............but when i use it for some other provider it gives an output '#text' instead of giving 'channel' which is the intended output.......the following is my script plz help me out.
$url = 'http://ibnlive.in.com/ibnrss/rss/sports/cricket.xml';
$get = perform_curl($url);
$xml = new DOMDocument();
$xml -> loadXML($get['remote_content']);
$fetch = $xml -> documentElement;
$gettitle = $fetch -> firstChild -> nodeName;
echo $gettitle;
function perform_curl($rss_feed_provider_url){
$url = $rss_feed_provider_url;
$curl_handle = curl_init();
// Do we have a cURL session?
if ($curl_handle) {
// Set the required CURL options that we need.
// Set the URL option.
curl_setopt($curl_handle, CURLOPT_URL, $url);
// Set the HEADER option. We don't want the HTTP headers in the output.
curl_setopt($curl_handle, CURLOPT_HEADER, false);
// Set the FOLLOWLOCATION option. We will follow if location header is present.
curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
// Instead of using WRITEFUNCTION callbacks, we are going to receive the remote contents as a return value for the curl_exec function.
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
// Try to fetch the remote URL contents.
// This function will block until the contents are received.
$remote_contents = curl_exec($curl_handle);
// Do the cleanup of CURL.
curl_close($curl_handle);
$remote_contents = utf8_encode($remote_contents);
$handle = #simplexml_load_string($remote_contents);
$return_result = array();
if(is_object($handle)){
$return_result['handle'] = true;
$return_result['remote_content'] = $remote_contents;
return $return_result;
}
else{
$return_result['handle'] = false;
$return_result['content_error'] = 'INVALID RSS SOURCE, PLEASE CHECK IF THE SOURCE IS A VALID XML DOCUMENT.';
return $return_result;
}
} // End of if ($curl_handle)
else{
$return_result['curl_error'] = 'CURL INITIALIZATION FAILED.';
return false;
}
}
php
it gives an output '#text' instead of giving 'channel' which is the intended output it happens because the $fetch -> firstChild -> nodeType is 3, which is a TEXT_NODE or just some text. You could select channel by
echo $fetch->getElementsByTagName('channel')->item(0)->nodeName;
and
$gettitle = $fetch -> firstChild -> nodeValue;
var_dump($gettitle);
gives you
string(5) "
"
or spaces and a new line symbol which happens to appear between the xml tags due to formatting.
ps: and RSS feed by your link fails validation at http://validator.w3.org/feed/
Take a look at the XML - it's been pretty printed with whitespace so it is being parsed correctly. The first child of the root node is a text node. I'd suggest using SimpleXML if you want an easier time of it, or use XPath queries on your DomDocument to obtain the tags of interest.
Here's how you'd use SimpleXML
$xml = new SimpleXMLElement($get['remote_content']);
print $xml->channel[0]->title;
I have this piece of code below which works fine on my remote hosted server, but isnt for some reason working on my local linux machine. Ive tried using file_get_contents as well to get the restful service but it also returns false.
Does anyone know Why this is happening?
thanks :)
$xml_data = simplexml_load_file("****");
if ($xml == FALSE)
{
echo "Failed loading XML\n";
foreach (libxml_get_errors() as $error)
{
echo "\t", $error->message;
}
}
You are getting this error because remote file access has been disabled on your server. An alternative to this is using CURL.
Use my code below to use CURL:
function produce_XML_object_tree($raw_XML) {
libxml_use_internal_errors(true);
try {
$xmlTree = new SimpleXMLElement($raw_XML);
} catch (Exception $e) {
// Something went wrong.
$error_message = 'SimpleXMLElement threw an exception.';
foreach(libxml_get_errors() as $error_line) {
$error_message .= "\t" . $error_line->message;
}
trigger_error($error_message);
return false;
}
return $xmlTree;
}
$xml_feed_url = '******';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);
$cont = produce_XML_object_tree($xml);
Now use $cont as an object to access different nodes in the xml.
Make sure you have allow_url_fopen turned on in your php.ini
http://php.net/manual/filesystem.configuration.php
Well I had same issue and though I would post this to assist anyone who may have not tried this solution yet.
I had a PHP script which worked fine locally, but when using it on a client server running plesk it would not work and failed when trying to grab the external xml file.
I was trying to reference an external xml file from a php script. The server I was using was running plesk. Before considering changing host, All I simply did was update the settings for PHP on the server to run as an Apache Module instead of FastCGI.
error message which I was receiving (example):
Warning: simplexml_load_file(url) [function.simplexml-load-file]: failed to open stream: Permission denied
This resolved the issue in my case.
I used following reports settings in the PHP script:
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_BAIL, 1);
assert_options(ASSERT_QUIET_EVAL, 1);
error_reporting(E_ALL);
ini_set('display_errors', 1);
use like this
$xml = simplexml_load_file('http://localhost/test/123.xml');
foreach ($xml->children() as $child) {
$remoteCount[$child->getName()] = $child;
}
var_dump($remoteCount);
Change: if ($xml == FALSE) to if ($xml === FALSE) (source).
I had the same problem it's just a stupid undeclared point in the simplexml
the xml file format should have a container tag, so, you just have to put a parent tag containing all your data like this:
<?xml version="1.0">
<data>
...all your file content here...
</data>
In my case, it's missing the XML php library, reinstall it and works fine
https://wpml.org/forums/topic/fatal-error-uncaught-error-call-to-undefined-function-simplexml_load_file-3/
I tried to post to wordpress blog from extrnal php code , all of my files are in the same directory, public_html.
this is my code:
function wpPostXMLRPC1($title,$body,$rpcurl,$username,$password,$category,$keywords='',$encoding='UTF-8') {
$title = htmlentities($title,ENT_NOQUOTES,$encoding);
$keywords = htmlentities($keywords,ENT_NOQUOTES,$encoding);
$content = array(
'title'=>$title,
'description'=>$body,
'mt_allow_comments'=>0, // 1 to allow comments
'mt_allow_pings'=>0, // 1 to allow trackbacks
'post_type'=>'post',
'mt_keywords'=>$keywords,
'categories'=>array($category)
);
$params = array(0,$username,$password,$content,true);
$request = xmlrpc_encode_request('metaWeblog.newPost',$params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$results = curl_exec($ch);
curl_close($ch);
return $results;
}
but its wrong, the error is
Fatal error: Call to undefined function xmlrpc_encode_request()
i can post to my wordpress blog with microsoft word(publish->blogPost), so Help me
PHP's xmlrpc extension seems to be not enabled on your server.
Wordpress using http://scripts.incutio.com/xmlrpc/ as xmlrpc server, you don't need xmlrpc extension to post to your wp. Just follow the instruction http://scripts.incutio.com/xmlrpc/advanced-client-construction.php.
But if you want to post on another way, such as posting by email you can follow this tutorial codex.wordpress.org/Post_to_your_blog_using_email
I struggled with the same. I found a similar problem somewhere else on the net and tweaked to to fit Wordpress. Mind you Wordpress install (wordpress.org), not the blog hosting service at wordpress.com. This should be working provided you have curl and xmlwriter enabled:
<?php
class atompub
{
//public $parae = '';
function __construct($one, $two, $three, $four)
{
$this->author=$one;
$this->title=$two;
$this->categories=$three;
$this->body=$four;
}
function create_post()
{
$xmlwriter = new XMLWriter();
$xmlwriter->openMemory();
$xmlwriter->startDocument("1.0", "UTF-8");
$xmlwriter->startElement('entry');
$xmlwriter->writeAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$xmlwriter->startElement('author');
$xmlwriter->writeElement('name', $this->author);
$xmlwriter->endElement();
$xmlwriter->writeElement('title', $this->title);
$xmlwriter->startElement('content');
$xmlwriter->writeAttribute('type', 'html');
$xmlwriter->text($this->body);
$xmlwriter->endElement();
$xmlwriter->startElement('category');
$xmlwriter->writeAttribute('term', $this->categories);
$xmlwriter->endElement();
$xmlwriter->endElement();
$xmlwriter->endDocument();
return $xmlwriter->outputMemory();
}
function __destruct()
{
}
}
$target = "<URL til your WordPress installation>/wp-app.php/posts";
// Note that the directory "posts" are used for posting (POST method)
// "service" is used to pull info via the GET method (not shown here)
$user = "XXX"; // Substitue XXX with your WordPress username
$passwd = "YYY"; // Substitue XXX with your WordPress password
$author='Your Name';
$title='The title of your choice for your new entry';
$array_of_categories='Category';
$body='This is the main body. All the text goes in here';
$xml_post = new atompub($author,$title,$array_of_categories,$body);
$post = $xml_post->create_post();
$headers = array("Content-Type: application/atom+xml ");
$handle = curl_init($target);
$curlopt_array = array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERPWD => $user.':'.$passwd,
CURLOPT_FOLLOWLOCATION => true,
CURLINFO_HEADER_OUT => true);
curl_setopt_array($handle, $curlopt_array);
$result = curl_exec($handle);
//var_dump($result);
$header_sent=curl_getinfo($handle);
//var_dump($header_sent);
if ($result === false) {
print "Got " . curl_errno($handle) . " : " . curl_error($handle) . "\n";
curl_close ($handle);
return;
}
$response_http_code = curl_getinfo ($handle, CURLINFO_HTTP_CODE);
if ($response_http_code != 201) {
print("HTTP status code: $response_http_code \n");
curl_close($handle);
return;
}
curl_close($handle);
?>
This should work directly, but you need to change the strings indicated (Blog URL, username, password, author, etc...). Beware that the login in insecure. This is only for demonstrating the functionality. You may also want to change the response code handling (which isn't mine, it came along with the original example which this is based upon).
On success Wordpress returns XML to you with details of the post event.
Fatal error: Call to undefined function xmlrpc_encode_request()
some times this error appear because xmlrpc extension is disabled.
execute phpinfo() to see if xmlrpc module displays or not.
If not, you need to enable it from php.ini by removing the semicolon, like
;extension=php_xmlrpc.dll to extension=php_xmlrpc.dll
and then restart Apache