1

http://xmlfeeds.centrebet.com/xmlRugbyLeaguefeed.xmlから特定のデータを解析して取得したい次のフィードがあります

以前は、クラスを使用してXMLを配列にプルすることでこれを行うことができました。現在、いくつかの問題が発生しています。ほぼ毎週変更が加えられているため、特定のキーワードに基づいているため、取得を自動化するのが困難になっています。

XMLから取得したいのは、TopLevelName = "NRL Round 18"の属性を持つマスターイベントのみです(これは明らかに毎週ラウンド19、20などに変更されます)

次に、そのマスターイベントの下にある各イベントについて、以下を取得するだけで済みます。

  • 各「競合他社/競合他社名」の「ストレートベット」「価格」
  • EventURL
  • 競合他社の名前

コードが非常に複雑だったため、コードを破棄しましたが、必要に応じて貼り付けることができます。このXMLパーサー http://www.bin-co.com/php/scripts/xml2array/を使用していました。

4

3 に答える 3

3

SimpleXML、XPath、およびfor-eachループを使用すると、これを非常に簡単に行うことができます。

SimpleXMLオブジェクトで覚えておくべきことがいくつかあります。

  • 各要素はSimpleXMLElement
  • SimpleXMLElement配列表記を使用してaの属性にアクセスします(例Element['attributeName']:)
  • オブジェクト表記(例、Element->ChildElementsまたはElement->{Child-Element-With-Strange-Name})を使用して特定の名前の子要素にアクセスする
  • (string) Elementテキスト値(例または(string) Element['attribute'])を取得するには、常に文字列にキャストします
  • より洗練されたクエリの場合は、このxpathメソッドを使用します。
  • 名前空間のある要素にアクセスするには、childrenメソッドの最初の引数を使用します。

一般に、中程度のサイズのデータ​​構造化(対ドキュメント構造化)XMLがある場合は常に、抵抗が最小のパスはですSimpleXML。非常に大きなドキュメントがある場合は、の組み合わせを使用しXMLReaderてドキュメントをチャンクに分割し、またはXMLReader::expand()を使用してそれらのチャンクを処理します。DOMDocumentSimpleXML

次の関数は、必要なデータを構造化配列に抽出します。

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 に答える