1

我有以下提要,我希望从 http://xmlfeeds.centrebet.com/xmlRugbyLeaguefeed.xml解析和获取某些数据

虽然我过去可以使用一个类将 XML 拉入一个数组来做到这一点。我现在遇到了一些并发症,几乎每周都会发生一些变化,这使得抓取的自动化变得困难,因为我是基于特定的关键字进行抓取的。

我想从 XML 中获取的只是具有 TopLevelName="NRL Round 18" 属性的主事件(这显然会每周更改为第 19 轮、第 20 轮等)

然后,我只需要为该 masterevent 下的每个事件获取以下信息

  • 每个“竞争对手/竞争对手名称”的“直接投注”“价格”
  • 事件网址
  • 竞争对手名称

我已经废弃了我的代码,因为它过于复杂,但如果你愿意,可以粘贴它,我正在使用这个 XML 解析器 http://www.bin-co.com/php/scripts/xml2array/

4

3 回答 3

3

您可以使用SimpleXML、 XPath 和 for-each 循环非常轻松地做到这一点。

对于 SimpleXML 对象,只需记住以下几点:

  • 每个元素变成一个SimpleXMLElement
  • SimpleXMLElement使用数组表示法访问 a 的属性(例如, Element['attributeName']
  • 使用对象表示法访问特定名称的子元素(例如,Element->ChildElementsElement->{Child-Element-With-Strange-Name}
  • 始终转换为字符串以获取文本值(例如(string) Elementor (string) Element['attribute']
  • 对于更高级的查询,请使用该xpath方法。
  • 要访问命名空间元素,请使用children方法的第一个参数。

通常,只要您拥有中等大小的数据结构化(相对于文档结构化)XML,阻力最小的路径就是SimpleXML. 如果您有一个非常大的文档,请使用组合XMLReader将文档分成块,并XMLReader::expand()使用DOMDocument或处理这些块SimpleXML

以下函数会将您想要的数据提取到结构化数组中:

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);

从这里将这些数据插入数据库是一件简单的事情(下面的代码未经测试):

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);
}
于 2012-07-03T04:02:19.173 回答
1

正如@MDrollette 所建议的,SimpleXML解析器可能是最好的方法。结合XPath进行一些搜索,您应该能够构建一个快速、灵活的解析器来获取您需要的数据。

这是一个快速示例,它将以多维数组的形式获取您所追求的数据。您需要对其进行修改以最适合您的应用程序。

$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);
于 2012-07-03T03:57:01.177 回答
0

您可以使用标准SimpleXML 解析器。这里有很多例子http://php.net/manual/en/simplexml.examples-basic.php

这比尝试使用数组灵活得多。

于 2012-07-03T03:36:07.327 回答