SimpleXML get next/prev node - php

I'm building a photo gallery, building an object based on an xml file.
How can I grab the next and previous nodes? Here's what my base code looks like:
$xmlData = new SimpleXMLElement(file_get_contents("data.xml"));
foreach($xmlData->row as $item) {
if ($item->url == $_GET['id']) {
// show photo
$title = $item->title;
}
}

Only usable if the next/prev nodes are of the same type. If you want more complex processing use DOM.
$xmlData = new SimpleXMLElement(file_get_contents("data.xml"));
$index = 0;
foreach($xmlData->row as $item) {
if ($item->url == $_GET['id']) {
// show photo
$title = $item->title;
$prev = $xmlData->row[$index-1];
$next = $xmlData->row[$index+1];
}
$index++;
}

Related

getting the main image from another url?

I have a function which returns all img links of any web page but i want to take the image that represent the news article best . I know that it is a little hard question but every news articles have some main image on top of the article . I need to pick it among all of other images . Facebook and reddit like sites can do that . Do you have any kind of idea ? When members of my website shared a link , there should be a picture for it . I can take all url of images in a web page now i need to find main image . :)
function get_links($url) {
$xml = new DOMDocument();
libxml_use_internal_errors(true);
$html = file_get_contents($url);
if(!$xml->loadHTML($html)) {
$errors="";
foreach (libxml_get_errors() as $error) {
$errors.=$error->message."<br/>";
}
libxml_clear_errors();
print "libxml errors:<br>$errors";
return;
}
// Empty array to hold all links to return
$links = array();
//Loop through each <img> tag in the dom and add it to the link array
foreach ($xml->getElementsByTagName('img') as $link) {
$url = $link->getAttribute('src');
if (!empty($url)) {
$links[] = $link->getAttribute('src');
}
}
//Return the links
return $links;
}
You can improve your existing function, but if you want to preference the existence of the Open Graph data, add this before your getElementsByTagName('img') logic...
$xpath = new DOMXPath( $xml );
if( $xpathNodeList = $xpath->query('//meta[#property="og:image" and #content]') )
{
return array( $xpathNodeList->item(0)->getAttribute('content') );
}
or add it to your array...
// Empty array to hold all links to return
$links = array();
$xpath = new DOMXPath( $xml );
if( $xpathNodeList = $xpath->query('//meta[#property="og:image" and #content]') )
{
$links[] = $xpathNodeList->item(0)->getAttribute('content');
}

viewing XML data if attribute value equals variable value

I'm stuck on something extremely simple.
Here is my xml feed:
http://xml.betfred.com/Horse-Racing-Daily.xml
Here is my code
<?php
function HRList5($viewbets) {
$xmlData = 'http://xml.betfred.com/Horse-Racing-Daily.xml';
$xml = simplexml_load_file($xmlData);
$curdate = date('d/m/Y');
$new_array = array();
foreach ($xml->event as $event) {
if($event->bettype->attributes()->bettypeid == $viewbets){//$_GET['evid']){
// $eventid = $_GET['eventid'];
// if ($limit == $c) {
// break;
// }
// $c++;
$eventd = substr($event->attributes()->{'date'},6,2);
$eventm = substr($event->attributes()->{'date'},4,2);
$eventy = substr($event->attributes()->{'date'},0,4);
$eventt = $event->attributes()->{'time'};
$eventid = $event->attributes()->{'eventid'};
$betname = $event->bettype->bet->attributes()->{'name'};
$bettypeid = $event->bettype->attributes()->{'bettypeid'};
$betprice = $event->bettype->bet->attributes()->{'price'};
$betid = $event->bettype->bet->attributes()->{'id'};
$new_array[$betname.$betid] = array(
'betname' => $betname,
'viewbets' => $viewbets,
'betid' => $betid,
'betname' => $betname,
'betprice' => $betprice,
'betpriceid' => $event->bettype->attributes()->{'betid'},
);
}
ksort($new_array);
$limit = 10;
$c = 0;
foreach ($new_array as $event_time => $event_data) {
// $racedate = $event_data['eventy'].$event_data['eventm'].$event_data['eventd'];
$today = date('Ymd');
//if($today == $racedate){
// if ($limit == $c) {
// break;
//}
//$c++;
$replace = array("/"," ");
// $eventname = str_replace($replace,'-', $event_data['eventname']);
//$venue = str_replace($replace,'-', $event_data['venue']);
echo "<div class=\"units-row unit-100\">
<div class=\"unit-20\" style=\"margin-left:0px;\">
".$event_data['betprice']."
</div>
<div class=\"unit-50\">
".$event_data['betname'].' - '.$event_data['betprice']."
</div>
<div class=\"unit-20\">
<img src=\"betnow.gif\" ><br />
</div>
</div>";
}
}//echo "<strong>View ALL Horse Races</strong> <strong>>></strong>";
//var_dump($event_data);
}
?>
Now basically the XML file contains a list of horse races that are happening today.
The page I call the function on also declares
<?php $viewbets = $_GET['EVID'];?>
Then where the function is called I have
<?php HRList5($viewbets);?>
I've just had a play around and now it displays the data in the first <bet> node
but the issue is it's not displaying them ALL, its just repeating the 1st one down the page.
I basically need the xml feed queried & if the event->bettype->attributes()->{'bettypeid'} == $viewbets I want the bet nodes repeated down the page.
I don't use simplexml so can offer no guidance with that - I would say however that to find the elements and attributes you need within the xml feed that you ought to use an XPath query. The following code will hopefully be of use in that respect, it probably has an easy translation into simplexml methods.
Edit: Rather than targeting each bet as the original xpath did which then caused issues, the following should be more useful. It targets the bettype and then processes the childnodes.
/* The `eid` to search for in the DOM document */
$eid=25573360.20;
/* create the DOM object & load the xml */
$dom=new DOMDocument;
$dom->load( 'http://xml.betfred.com/Horse-Racing-Daily.xml' );
/* Create a new XPath object */
$xp=new DOMXPath( $dom );
/* Search the DOM for nodes with particular attribute - bettypeid - use number function from XSLT to test */
$oCol=$xp->query('//event/bettype[ number( #bettypeid )="'.$eid.'" ]');
/* If the query was successful there should be a nodelist object to work with */
if( $oCol ){
foreach( $oCol as $node ) {
echo '
<h1>'.$node->parentNode->getAttribute('name').'</h1>
<h2>'.date('D, j F, Y',strtotime($node->getAttribute('bet-start-date'))).'</h2>';
foreach( $node->childNodes as $bet ){
echo "<div>Name: {$bet->getAttribute('name')} ID: {$bet->getAttribute('id')} Price: {$bet->getAttribute('price')}</div>";
}
}
} else {
echo 'XPath query failed';
}
$dom = $xp = $col = null;

Taking node values from a site, and re-outputting only selected node tags that can be styled

I am pulling my hair trying to get this to work with php.
The problem: I am just trying to scrape products off a site and have them display as a list of products without anything else that I can style in css. What I'd like to output is <div id='product'><a href= $link ><img src= $image /></a><br/><p>$productText</p></div> as a list of products for a site (basically scrape them). This is a project I am trying for fun, here is the code:
$html = new DOMDocument();
#$html->loadHtmlFile('http://www.amazon.com/gp/search/ref=sr_nr_p_8_3?rh=n%3A2619533011%2Ck%3Apet+products%2Cn%3A%212619534011%2Cn%3A2975312011%2Cp_72%3A2661618011%2Cp_8%3A2661607011&bbn=2975312011&keywords=pet+products&ie=UTF8&qid=1328429080&rnid=2661603011#/ref=sr_st?bbn=2975312011&keywords=pet+products&qid=1328429127&rh=n%3A2619533011%2Ck%3Apet+products%2Cn%3A!2619534011%2Cn%3A2975312011%2Cp_72%3A2661618011%2Cp_8%3A2661607011');
$xpath = new DOMXPath( $html );
$productName = $xpath->query( "//div[#id='btfResults']/div/div[4]/div[1]/a/text()" );
$link = $xpath->query( "//div[#id='btfResults']/div/div[3]/a/#href" );
$image = $xpath->query( "//div[#id='btfResults']/div/div[3]/a/img/#src" );
foreach ($productName as $n){
$productText = $n->nodeValue;
}
foreach ($image as $n){
$imageLink = $n->nodeValue;
}
foreach ($link as $n){
$linkLink = $n->nodeValue;
}
foreach ($link as $n)
{
echo "<div id='product'><a href= $linkLink ><img src= $imageLink /></a><br/><p>$productText</p></div>";
}
The truth is I have no clue how to get the right results I want. Let me know if this needs further explaining. Thanks!
Fixed and tested:
<?php
$html = new DOMDocument();
#$html->loadHtmlFile('http://www.amazon.com/gp/search/ref=sr_nr_p_8_3?rh=n%3A2619533011%2Ck%3Apet+products%2Cn%3A%212619534011%2Cn%3A2975312011%2Cp_72%3A2661618011%2Cp_8%3A2661607011&bbn=2975312011&keywords=pet+products&ie=UTF8&qid=1328429080&rnid=2661603011#/ref=sr_st?bbn=2975312011&keywords=pet+products&qid=1328429127&rh=n%3A2619533011%2Ck%3Apet+products%2Cn%3A!2619534011%2Cn%3A2975312011%2Cp_72%3A2661618011%2Cp_8%3A2661607011');
$xpath = new DOMXPath( $html );
$btfResults = $xpath->query("//div[#id='btfResults']/div"); // get all item nodes
foreach ($btfResults as $node) // iterate through all items
{
$productText = $linkLink = $imageLink = null; // reset result variables for each loop
if ($productName = $xpath->query("./div[4]/div[1]/a/text()", $node)->item(0)) // fetch productName node from the item
{
$productText = $productName->nodeValue;
}
if ($link = $xpath->query("./div[3]/a/#href", $node)->item(0)) // fetch link node from the item
{
$linkLink = $link->nodeValue;
}
if ($image = $xpath->query("./div[3]/a/img/#src", $node)->item(0)) // fetch image node from the item
{
$imageLink = $image->nodeValue;
}
if ($productText && $linkLink && $imageLink) // only return a result when all variables are set.
{
echo '<div id="product"><img src="'.$imageLink.'"/><br/><p>'.$productText.'</p></div>';
}
}

php error when XML item does not exist

I am using PHP to grab an XML feed and display it in my website, the feed is coming from
This NewsReach Blog.
I am using some simple PHP code to get the details as show below:
$feed = new SimpleXMLElement('http://blog.newsreach.co.uk/atom.xml', null, true);
$i = 0;
foreach($feed->entry as $entry)
{
if ($i < 4)
{
$title = mysql_real_escape_string("{$entry->title}");
$summary = mysql_real_escape_string("{$entry->content}");
$summary = strip_tags($summary);
$summary = preg_replace('/\s+?(\S+)?$/', '', substr($summary, 0, 100));
$url = mysql_real_escape_string("{$entry->link[4]['href']}");
$media = $entry->children('http://search.yahoo.com/mrss/');
$attrs = $media->thumbnail[0]->attributes();
$img = $attrs['url'];
}
}
The problem that I have is that the media thumbnail tag does not exist in every blog post which causes an error to appear and stop the XML Grabber from functioning.
I have tired things like:
if ($media == 0)
{
}
else
{
$attrs = $media->thumbnail[0]->attributes();
$img = $attrs['url'];
}
or
if ($media['thumbnail'] == 0)
{
}
else
{
$attrs = $media->thumbnail[0]->attributes();
$img = $attrs['url'];
}
which I had no luck with, I was hoping someone could help me check if the XML Item existed and then process depending on that.
Thanks all
You could check if it's set and not empty:
$img = '';
if (!empty($media->thumbnail[0])) {
$attrs = $media->thumbnail[0]->attributes();
$img = $attrs['url'];
}
Remember that $media is an object, you can't access it like an array ($media['thumbnail'] should be $media->thumbnail).

How to print element values when iterating through XML document in PHP

I am iterating through the results of a service call to yahoo news thus:
//Send service request
if (!$yahooResults = file_get_contents($yahooRequest)) {
echo 'Error processing service request';
}
//Read result into xml document
$yahooResultXml = new DOMDocument('1.0', 'UTF-8');
$yahooResultXml->loadXML($yahooResults);
//Build page
include_once('components/pageHeader.php');
echo 'Search Results';
//echo $yahooResultXml->saveHTML();
//Iterate over each Result node
$stories = $yahooResultXml->getElementsByTagName('Result');
foreach ($stories as $story) {
//Title
//Summary
//Url
//Source
//Language
//Publish Date
//Modification Date
}
include_once('components/pageFooter.php');
Each Title is in a Title node within a Result Node. I cannot figure out how to simply echo the content of the Title node!
Check the first user comment at PHP: DOMDocument::getElementsByTagName
$items =
$doc->getElementsByTagName('item');
$headlines = array();
foreach($items as $item) {
$headline = array();
if($item->childNodes->length) {
foreach($item->childNodes as $i) {
$headline[$i->nodeName] =
$i->nodeValue;
}
}
$headlines[] = $headline;
}

Categories