Reputation: 149
I have the following feed which I wish to parse and grab certain data from http://xmlfeeds.centrebet.com/xmlRugbyLeaguefeed.xml
Whilst I was able to do this in past using a class to pull the XML into an array. I am suffering a few complications with it now, and there have been changes almost weekly that have made it hard to automate the grabbing as I was basing it on specific keywords.
What I want to grab from the XML is only the master events that have the attribute of TopLevelName="NRL Round 18" (this will obviously change each week to round 19, 20 etc)
I then only need to get the following for each of the events under that masterevent
I ave scrapped my code as it was overly complex but can paste it if you like, I was using this XML parser http://www.bin-co.com/php/scripts/xml2array/
Upvotes: 1
Views: 1361
Reputation: 31621
You can do this very easy with SimpleXML, XPath, and for-each loops.
There are only a few things to keep in mind with SimpleXML objects:
SimpleXMLElement
SimpleXMLElement
with array-notation (e.g., Element['attributeName']
)Element->ChildElements
or Element->{Child-Element-With-Strange-Name}
)(string) Element
or (string) Element['attribute']
)xpath
method.children
method's first argument.In general, whenever you have data-structured (vs document-structured) XML of a moderate size, the path of least resistance is SimpleXML
. If you have a very large document, use a combination of XMLReader
to break the document up into chunks, and XMLReader::expand()
to process those chunks using DOMDocument
or SimpleXML
.
The following function will extract the data you want into a structured array:
function extractDataFromFeed($feeduri) {
$events = array();
$sxe = simplexml_load_file($feeduri);
$targetMasterEvents = $sxe->xpath('/EventData/MasterEvents[starts-with(./@TopLevelName, "NRL Round ")]');
foreach ($targetMasterEvents as $targetMasterEvent) {
foreach ($targetMasterEvent->Event as $targetEvent) {
$event = array(
'EventUrl' => (string) $targetEvent['EventURL'],
'Competitors' => array(), // CompetitorName => StraightBetPrice,
// (assumes 1 price per competitorname)
);
foreach ($targetEvent->Competitors as $targetCompetitor) {
$targetBets = $targetCompetitor->xpath('BetType[@BetTypeName="Straight Bet"]');
foreach ($targetBets as $targetBet) {
$event['Competitors'][(string) $targetCompetitor['CompetitorName']]
= (string) $targetBet['Price'];
}
}
}
$events[] = $event;
}
return $events;
}
$FEED = 'http://xmlfeeds.centrebet.com/xmlRugbyLeaguefeed.xml';
$events = extractDataFromFeed($FEED);
var_export($events);
From here it is a simple matter to insert this data into a database (code below is untested):
function insertEvents($eventname, $events, PDO $pdo) {
// Set exception mode (if not set already)
$old_ERRMODE = $pdo->getAttribute(PDO::ATTR_ERRMODE);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// create prepared statements
$insertEvent = $pdo->prepare('INSERT INTO events (EventName, EventURL) VALUES (?,?)');
$insertBet = $pdo->prepare('INSERT INTO bets (event_id, CompetitorName, Price) VALUES (?,?,?)');
// bind statement parameters
$insertEvent->bindValue(1, $eventName, PDO::PARAM_STR);
$insertEvent->bindParam(2, $eventURL, PDO::PARAM_STR);
$insertBet->bindParam(1, $event_id, PDO::PARAM_INT);
$insertBet->bindParam(2, $competitorName, PDO::PARAM_STR);
$insertBet->bindParam(3, $price);
// loop through event array, executing inserts
foreach($events as $event) {
$eventUrl = $event['EventURL'];
$insertEvent->execute();
$event_id = $pdo->lastInsertId();
foreach($event['Competitors'] as $competitorName => $price) {
$insertBet->execute();
}
}
// restore ERRMODE setting (won't be restored if exception is raised!)
$pdo->setAttribute(PDO::ATTR_ERRMODE, $old_ERRMODE);
}
Upvotes: 3
Reputation: 8415
As @MDrollette suggested, SimpleXML parser is probably the best way. Combined with XPath to do some searching, you should be able to build a quick, flexible parser to get the data you need.
This is a quick example that will grab the data you are after as a multi-dimensional array. You'll need to revise it to best match what will work for your application.
$xml = new SimpleXMLElement($string);
// Find all the MasterEvents we are looking for
$masterevents = $xml->xpath('//MasterEvents[@TopLevelName="NRL Round 18"]');
$me_array = array();
foreach ($masterevents as $masterevent) {
$event_array = array();
// Loop through the Events
foreach($masterevent->Event as $event) {
$event_array['url'] = (string)$event['EventURL'];
// Loop through the competitors / betting
foreach($event->Competitor as $competitor) {
$competitor_array = array();
$competitor_array['name'] = (string)$competitor['CompetitorName'];
$competitor_array['bettype'] = (string)$competitor->BetType[0]['BetTypeName'];
$competitor_array['betprice'] = (string)$competitor->BetType[0]['Price'];
$event_array['competitors'][] = $competitor_array;
}
}
$me_array[] = $event_array;
}
// Dump out the results for as a demo
var_dump($me_array);
Upvotes: 1
Reputation: 6927
You can use the standard SimpleXML parser. There are plenty of example here http://php.net/manual/en/simplexml.examples-basic.php
This is much more flexible than trying to use arrays.
Upvotes: 0