Take form data and write it to XML file - php

I am trying to take form data (via _POST) and write it to a document using SimpleXML. This is what I have tried and I can't seem to get it to work.
<?php
$title = $_POST['title'];
$link = $_POST['link'];
$description = $_POST['description'];
$rss = new SimpleXMLElement($xmlstr);
$rss->loadfile("feed.xml");
$item = $rss->channel->addChild('item');
$item->addChild('title', $title);
$item->addChild('link', $link);
$item->addChild('description', $description);
echo $rss->asXML();
header("Location: /success.html");
exit;
?>
Any help or a point in the right direction would be much appreciated.

You use the asXML() function wrong. If you want to write your XML to a file, you must pass a filename parameter to it. Check the SimpleXMLElement::asXML manual
so your code line oututing xml should be changed from
echo $rss->asXML();
to
$rss->asXML('myNewlyCreatedXML.xml');

rather than using SimpleXMLElement you can create XML directly like this
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= '<item>';
$xml .= '<title>'.$title.'</title>';
$xml .= '<link>'.$title.'</link>';
$xml .= '<description>'.$title.'</description>';
$xml .= '</item>';
$xml_file = "feed.xml";
file_put_contents($xml_file,$xml);
may this will help you

There are a few problems with your code
<?php
$title = $_POST['title'];
$link = $_POST['link'];
$description = $_POST['description'];
//$rss = new SimpleXMLElement($xmlstr); // need to have $xmlstr defined before you construct the simpleXML
//$rss->loadfile("feed.xml");
//easier to just load the file when creating your XML object
$rss = new SimpleXML("feed.xml",null,true) // url/path, options, is_url
$item = $rss->channel->addChild('item');
$item->addChild('title', $title);
$item->addChild('link', $link);
$item->addChild('description', $description);
//header("Location: /success.html");
//if you want to redirect you should put a timer on it and echo afterwards but by
//this time if something went wrong there will be output already sent,
//so you can't send more headers, i.e. the next line will cause an error
header('refresh: 4; URL=/success.html');
echo $rss->asXML(); // you may want to output to a file, rather than the client
// $rss->asXML('outfputfile.xml');
exit;
?>

Related

Open image of the singer by LastFM and function (artist.getinfo)

Good, I have this code of LastFM API
<?php
$xml = simplexml_load_file("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=ARIANA GRANDE&api_key=b25b959554ed76058ac220b7b2e0a026");
$largeImage = $xml->xpath('/lfm/artist/image[#size="mega"]')[0];
echo '<img src="'.$largeImage.'" />';
?>
it appears used the image of Ariana Grande a php page.
Now the link of my XML file is :http://radiojoven.6te.net/playlist.xml
Well, what I am trying to do is change "ARIANA GRANDE" (the artist's name) in the link of the "simplexml_load_file" (in the php code) with the info that my XML file provides. I tried to make a code like this but to no avail.
<?php
$xml = simplexml_load_file('http://radiojoven.6te.net/playlist.xml');
$artist = urlencode($xml->Event->Song->Artist['name'];);
$url = simplexml_load_file("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist='.$artist.'&api_key=50ac27433c63f7298064f434f4ef6d15);
$xml2 = #simplexml_load_file($url);
$largeImage = $xml2->xpath('/lfm/artist/image[#size="mega"]')[0];
echo '<img src="'.$largeImage.'" />';
?>
Can you please help me doing this?
Thank you all in advance.
I think there are a few errors in your code.
Remove the semicolon after ['name']; in this line:
$artist = urlencode($xml->Event->Song->Artist['name'];);
Missing double quotes after api_key=50ac27433c63f7298064f434f4ef6d15 and I think '.$artist.' should be $artist in this line:
$url = simplexml_load_file("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist='.$artist.'&api_key=50ac27433c63f7298064f434f4ef6d15);
I don't think that you need this line:
$xml2 = #simplexml_load_file($url);
Then in this line change $xml2 to $url:
$largeImage = $xml2->xpath('/lfm/artist/image[#size="mega"]')[0];
So your code would become like this:
<?php
$xml = simplexml_load_file('http://radiojoven.6te.net/playlist.xml');
$artist = urlencode($xml->Event->Song->Artist['name']);
$url = simplexml_load_file("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=$artist&api_key=50ac27433c63f7298064f434f4ef6d15");
$largeImage = $url->xpath('/lfm/artist/image[#size="mega"]')[0];
echo '<img src="'.$largeImage.'" />';
?>

Display rss xml index in html

I am adding an RSS feed to my website. I created the RSS.xml index file and next I want to display its contents in a nicely formatted way in a webpage.
Using PHP, I can do this:
$index = file_get_contents ($path . 'RSS.xml');
echo $index;
But all that does is dump the contents as a long stream of text with the tags removed.
I know that treating RSS.xml as a link, like this:
<a href="../blogs/RSS.xml">
<img src="../blogs/feed-icon-16.gif">Blog Index
</a>
causes my browser to parse and display it in a reasonable way when the user clicks on the link. However I want to embed it directly in the web page and not make the user go through another click.
What is the proper way to do what I want?
Use the following code:
include_once('Simple/autoloader.php');
$feed = new SimplePie();
$feed->set_feed_url($url);
$feed->enable_cache(false);
$feed->set_output_encoding('utf-8');
$feed->init();
$i=0;
$items = $feed->get_items();
foreach ($items as $item) {
$i++;
/*You are getting title,description,date of your rss by the following code*/
$title = $item->get_title();
$url = $item->get_permalink();
$desc = $item->get_description();
$date = $item->get_date();
}
Download the Simple folder data from : https://github.com/jewelhuq/Online-News-Grabber/tree/master/worldnews/Simple
Hope it will work for you. There $url mean your rss feed url. If you works then response.
Turns out, it's simple by using the PHP xml parer function:
$xml = simplexml_load_file ($path . 'RSS.xml');
$channel = $xml->channel;
$channel_title = $channel->title;
$channel_description = $channel->description;
echo "<h1>$channel_title</h1>";
echo "<h2>$channel_description</h2>";
foreach ($channel->item as $item)
{
$title = $item->title;
$link = $item->link;
$descr = $item->description;
echo "<h3><a href='$link'>$title</a></h3>";
echo "<p>$descr</p>";
}

Generate xml file with stylesheet using SimpleXML

I have a question about how to add a stylesheet to a SimpleXML generated XML file.
This is my code, but I don't know how to add a stylesheet for this.
$xml = new SimpleXMLElement('<Cart/>');
$Order = $xml->addChild('Person');
$Order->addChild('Name', $_GET['name']);
$Order->addChild('Last-name', $_GET['lname']);
$Order->addChild('E-mail', $_GET['email']);
$Order->addChild('Phone', $_GET['phone']);
$Order->addChild('Date', date('Y-m-d'));
$Order->addChild('Adress', isset($_GET['adress'])&&$_GET['adress'] != NULL?$_GET['adress']:'Not set');
$Products = $xml->addChild('Products');
foreach ($cart as $product_id) {
foreach($productlist as $list){
if($list['id'] == $product_id){
$Cart = $Products->addChild('Product');
$Cart->addChild('ID', $list['id']);
$Cart->addChild('Brand', $list['brand']);
$Cart->addChild('Model', $list['model']);
$Cart->addChild('Price', $list['price']);
}
}
}
Header('Content-type: text/xml');
date_default_timezone_set("Europe/Helsinki");
$xml->asXML('orders/' .date('Y-m-d(H-i-s)'). '.xml');
And this is the line that I want to add to the top of my generated XML file.
<?xml-stylesheet type="text/xsl" href="order.xsl" ?>
You can try just adding it before the root node
$xml = new SimpleXMLElement('<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="order.xsl"?><Cart/>');
you need to write
$xml->addProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="order.xsl"');
how to add function you can view here
SimpleXML insert Processing Instruction (Stylesheet)

XML Search and addChild

Here is what I have so far, I want to add date/time logs to the xml file.
<?php
// Load the XML file we want to write to
$visitors = simplexml_load_file("data.xml");
// Set e-mail xml search
$search_id = htmlentities($_POST['email']);
$visitors = $visitors->xpath("visitor[email='$search_id']");
// If we have a search result, email already exists in xml file
if(isset($visitors[0])){
$visitor = $visitors[0];
$email = (string) $visitor->email;
// ********** Need to add date/time for each visit here.
// So, I guess I need to search for e-mail address, then append to it.
// Help required here... and again below to confirm formatting for multiple
// dates.
} else {
$xml = simplexml_load_file("data.xml");
$sxe = new SimpleXMLElement($xml->asXML());
$search_id = preg_replace('/[^(\x20-\x7F)]*/','', $search_id);
$visitor = $sxe->addChild("visitor");
$visitor->addChild("email", $search_id);
// ******** Not sure this is the correct xml formatting.
$date = $visitor->addChild('date');
$date->addChild("email", date("Y-m-d H:i:s"));
$sxe->asXML("data.xml");
} // if(isset($visitors[0])){
} // if(isset($data)){ ?>
Which generates
<?xml version="1.0" encoding="utf-8"?>
<visitors>
<visitor>
<email>jon.doe#aol.com</email>
</visitor>
</visitors>
What I want to do is add a date log (incementing/appending) for each visit.
So the result would be (I am not sure my formatting is correct, which of course is not helping to matters). Don't worry about the PHP for the date/time.
<?xml version="1.0" encoding="utf-8"?>
<visitors>
<visitor>
<email>jon.doe#aol.com</email>
<date>2012-11-01 11:00:00</date>
<date>2012-11-02 14:00:00</date>
</visitor>
</visitors>
I think you were on the right track here, the main thing is that your call to asXML('data.xml') is inside your ELSE block, so the file only gets written to file if it is being created from scratch (ie. The search_id is not found).
I made a few changes, mostly to make it easier to follow. More changes to come!:
<?php
// Load the XML file we want to write to
$xmlFile = simplexml_load_file("data.xml");
// Set e-mail xml search
$search_id = 'jon.doe#aol.com';
$results = $xmlFile->xpath("visitor[email='$search_id']");
// If we have a search result, email already exists in xml file
if(isset($results[0]))
{
$visitor = $results[0];
$email = (string) $visitor->email;
echo "Found Email: " . $email . "\n";
echo "Date: " . $visitor->date . "\n";
// ********** Need to add date/time for each visit here.
// So, I guess I need to search for e-mail address, then append to it.
// Help required here... and again below to confirm formatting for multiple
// dates.
echo "Adding new date";
$visitor->addChild('date', date('Y-m-d H:i:s'));
echo "New XML: " . $xmlFile->asXML();
$xmlFile->asXML('data.xml');
} else {
$sxe = new SimpleXMLElement($xmlFile->asXML());
$search_id = preg_replace('/[^(\x20-\x7F)]*/','', $search_id);
$visitor = $sxe->addChild("visitor");
$visitor->addChild("email", $search_id);
// ******** Not sure this is the correct xml formatting.
$date = $visitor->addChild('date', date('Y-m-d H:i:s'));
$sxe->asXML("data.xml");
}
?>
After running this script a few times, I got:
<?xml version="1.0"?>
<visitors>
<visitor>
<email>jon.doe#aol.com</email>
<date>2012-11-03 02:13:28</date>
<date>2012-11-03 02:20:20</date>
<date>2012-11-03 02:22:07</date>
<date>2012-11-03 02:22:10</date>
<date>2012-11-03 02:22:13</date>
</visitor>
</visitors>
Which I think is what you want? Does this help?
EDIT:
Regarding your mentioning of whether or not it's the correct XML format. I suppose there's no exclusive right answer. I would say that this format is fine, provided that you remember to separate each individual email address / set of dates in its own visitor tags.
To do that, you'd probably want something like so (untested):
$newVisitor = $xmlFile->addChild('visitor');
$newVisitor->addChild('email', $newEmail);
$newVisotor->addChild('date', $newDate);
$xmlFile->asXML('data.xml');
EDIT 2:
One last thing that I've used in the past is the following code. It will format the XML much nicer, and will also prevent any corruption of the original XML file if you have any issues mid-save (or at least give you a backup). Personally, I try to make a habit of using a temporary file like this any time I have to write to file.
Of course, just add this, then replace your calls to:
$xmlFile->asXML('data.xml');
$sxe->asXML("data.xml");
With:
writeXML('data.xml', $xmlFile);
writeXML('data.xml', $sxe);
And it should work OK.
//Writes final version of the SimpleXML object to file.
//Includes writing to a temp file for safety.
//This way is safer because if the code crashes mid-write it won't garble the original file.
function writeXML($fileName, $xmlObject)
{
//Sanity check before copy, prevent any visible errors:
if (file_exists($fileName))
copy($fileName, $fileName . '.backup');
//Write to temp file first in-case something kills the write; don't want to corrupt the original.
$tmpName = $fileName . '~$.' . microtime();
$handle = fopen($tmpName, 'w');
fwrite($handle, formatXML($xmlObject));
fclose($handle);
copy($tmpName, $fileName);
unlink($tmpName);
}
//asXML does no indentation formatting, so we'll do it here instead. This is called by WriteXML so that we're writing formatted XML to file.
function formatXML($xmlObject)
{
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xmlObject->asXML());
return $dom->saveXML();
}
This is an addition to #Geekmans answer
Your code does not look too far of. However you can greatly improve it which is why add another answer here (I would have normally edited #Geekmans answer but it's already very large).
The point of improvement is in the program flow. If the email is not found, you don't need to create a new SimpleXMLElement, you only need to create a new <visitor> element. Then adding the <date> element as well as outputting the file is actually the same for both cases. This allows to remove the duplicate code:
// Specify the XML file we want to write to
$inFile = "data.xml";
// Set e-mail xml search and insert id
$search_id = 'jon.doe#aol.com';
$insert_id = preg_replace('/[^(\x20-\x7F)]*/', '', $search_id);
// Load the XML file we want to write to
$xmlFile = simplexml_load_file($inFile);
$results = $xmlFile->xpath("visitor[email='$search_id']");
// If we have a search result, email already exists in xml file
if ($results) {
$visitor = $results[0];
echo "Found Visitor: ", $visitor->email, "\n",
"First Date: ", $visitor->date, "\n";
} else {
echo "Adding new Visitor: ", $insert_id, "\n";
$visitor = $xmlFile->addChild("visitor");
$visitor->addChild("email", $insert_id);
}
echo "Adding new Date: ", $date = date('Y-m-d H:i:s'), "\n";
$visitor->addChild('date', $date);
echo "Changed XML: \n" . simplexml_pretty_print($xmlFile);
$xmlFile->asXML($inFile);
/**
* #param SimpleXMLElement $simplexml
* #link https://stackoverflow.com/a/798986/367456
*/
function simplexml_pretty_print(SimpleXMLElement $simplexml) {
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($simplexml->asXML());
return $dom->saveXML();
}
As a bonus I added the simplexml_pretty_print function to have the output in a nicer way.
The output for jon.doe#aol.com:
Found Visitor: jon.doe#aol.com
First Date: 2012-11-01 11:00:00
Adding new Date: 2012-11-03 10:48:05
Changed XML:
<?xml version="1.0" encoding="utf-8"?>
<visitors>
<visitor>
<email>jon.doe#aol.com</email>
<date>2012-11-01 11:00:00</date>
<date>2012-11-02 14:00:00</date>
<date>2012-11-03 10:48:05</date>
</visitor>
</visitors>
The output for info#example.com:
Adding new Visitor: info#example.com
Adding new Date: 2012-11-03 10:52:09
Changed XML:
<?xml version="1.0" encoding="utf-8"?>
<visitors>
<visitor>
<email>jon.doe#aol.com</email>
<date>2012-11-01 11:00:00</date>
<date>2012-11-02 14:00:00</date>
</visitor>
<visitor>
<email>info#example.com</email>
<date>2012-11-03 10:52:09</date>
</visitor>
</visitors>
Tip: Whenever you spot duplicate code, there often is a way to write it in a much simpler form.

PHP SimpleXML Breaking when trying to traverse nodes

I'm trying to read the xml information that tumblr provides to create a kind of news feed off the tumblr, but I'm very stuck.
<?php
$request_url = 'http://candybrie.tumblr.com/api/read?type=post&start=0&num=5&type=text';
$xml = simplexml_load_file($request_url);
if (!$xml)
{
exit('Failed to retrieve data.');
}
else
{
foreach ($xml->posts[0] AS $post)
{
$title = $post->{'regular-title'};
$post = $post->{'regular-body'};
$small_post = substr($post,0,320);
echo .$title.;
echo '<p>'.$small_post.'</p>';
}
}
?>
Which always breaks as soon as it tries to go through the nodes. So basically "tumblr->posts;....ect" is displayed on my html page.
I've tried saving the information as a local xml file. I've tried using different ways to create the simplexml object, like loading it as a string (probably a silly idea). I double checked that my webhosting was running PHP5. So basically, I'm stuck on why this wouldn't be working.
EDIT: Ok I tried changing from where I started (back to the original way it was, starting from tumblr was just another (actually silly) way to try to fix it. It still breaks right after the first ->, so displays "posts[0] AS $post....ect" on screen.
This is the first thing I've ever done in PHP so there might be something obvious that I should have set up beforehand or something. I don't know and couldn't find anything like that though.
This should work :
<?php
$request_url = 'http://candybrie.tumblr.com/api/read?type=post&start=0&num=5&type=text';
$xml = simplexml_load_file($request_url);
if ( !$xml ){
exit('Failed to retrieve data.');
}else{
foreach ( $xml->posts[0] AS $post){
$title = $post->{'regular-title'};
$post = $post->{'regular-body'};
$small_post = substr($post,0,320);
echo $title;
echo '<p>'.$small_post.'</p>';
echo '<hr>';
}
}
First thing in you code is that you used root element that should not be used.
<?php
$request_url = 'http://candybrie.tumblr.com/api/read?type=post&start=0&num=5&type=text';
$xml = simplexml_load_file($request_url);
if (!$xml)
{
exit('Failed to retrieve data.');
}
else
{
foreach ($xml->posts->post as $post)
{
$title = $post->{'regular-title'};
$post = $post->{'regular-body'};
$small_post = substr($post,0,320);
echo .$title.;
echo '<p>'.$small_post.'</p>';
}
}
?>
$xml->posts returns you the posts nodes, so if you want to iterate the post nodes you should try $xml->posts->post, which gives you the ability to iterate through the post nodes inside the first posts node.
Also as Needhi pointed out you shouldn't pass through the root node (tumblr), because $xml represents itself the root node. (So I fixed my answer).

Categories