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:
- Each element becomes a
SimpleXMLElement
- Access the attributes of a
SimpleXMLElement with array-notation (e.g., Element['attributeName'])
- Access child elements of a certain name with object-notation (e.g.,
Element->ChildElements or Element->{Child-Element-With-Strange-Name})
- Always cast to a string to get the text value (e.g.
(string) Element or (string) Element['attribute'])
- For fancier queries, use the
xpath method.
- To access namespaced elements, use the
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);
}