2011-08-19 3 views
2

내부 회계 시스템에 대한 과거 환율 기준율 목록을 가져와야합니다.XML로 XML에서 ECB 환율을 추출하는 데 어려움이 있습니다. 전체 소스 코드입니다.

이 질문은 다음 코드에 관한 것입니다. 유용하다고 생각되면이 코드를 자유롭게 사용하십시오. 물론 최종 "niggle"을 수정하는 대답을 얻은 후에는 DB 구조 덤프를 코드는 모든 DB 루틴은

데이터는 유럽 중앙 은행 XML에서 가져옵니다. 지금은 단지 반향, 디버그 데이터를 주석 http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml에서 찾을 수 있습니다

고정! 당신이 당겨해야하는 경우이 코드를 자유롭게 사용 DB에 역사적인 환율 값 목록 .. 에코 디버깅을 제거하고 DB 쿼리를 정렬하십시오.

<?php 

/* DB structure: 
CREATE TABLE IF NOT EXISTS `currency_rates_history` (
    `id` int(4) NOT NULL auto_increment, 
    `currency` char(3) character set utf8 collate utf8_unicode_ci NOT NULL default '', 
    `rate` float NOT NULL default '0', 
    `date` int(4) NOT NULL default '0', 
    `est` tinyint(1) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8_unicode_ci AUTO_INCREMENT=1 ; 

*/ 

error_reporting(E_ALL); 

$table = "currency_rates_history"; 

$secs = '86400'; 

$prev_date = time(); 

$days = "0"; 

$XML=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml"); // European Central Bank xml only contains business days! oh well.... 


foreach($XML->Cube->Cube as $time)               // run first loop for each date section 
{ 

    echo "<h1>".$time["time"].'</h1>'; 

    list($dy,$dm,$dd) = explode("-", $time["time"]); 

    $date = mktime(8,0,0,$dm,$dd,$dy); 

    echo ($prev_date - $date)."<br />"; 

    if(($prev_date - $date) > $secs)              // detect missing weekend and bank holiday values. 
    { 

     echo "ooh";                   // for debug to search the output for missing days 

     $days =(round((($prev_date - $date)/$secs),0)-1);         // got to remove 1 from the count.... 

     echo $days;                   // debug, will output the number of missing days 

    } 
    foreach($time->Cube as $_rate)            // That fixed it! run the 2nd loop and ad enter the new exchange values.... 
    { 

     $rate = floatval(str_replace(",", ".", $_rate["rate"])); 


     if($days > 0)                  // add the missing dates using the last known value, coul dbe more accurate but at least there is some reference data to work with 
     { 
      $days_cc = $days;                // need to keep $days in mem for the next currency 

      while($days_cc > 0) 
      { 
       echo $rate; 
       echo date('D',$date+($days_cc*$secs))."<br />"; 
       /* 
       mysql_query("LOCK TABLES {$table} WRITE"); 

       mysql_query("INSERT INTO {$table}(rate,date,currency,est) VALUES('{$rate}','".($date+($days_cc*$secs))."','{$currency}','1')"); 

       mysql_query("UNLOCK TABLES"); 
       */ 
       $days_cc = ($days_cc - 1); // count down 
      } 
     } 

     $currency = addslashes(strtolower($_rate["currency"])); 
     /* 
     mysql_query("LOCK TABLES {$table} WRITE"); 
//  mysql_query("UPDATE {$table} SET rate='{$rate}',date='{$date}' WHERE currency='{$currency}' AND date='{$date}'"); // all this double checking was crashing the script 
//  if (mysql_affected_rows() == 0) 
//  { 
      mysql_query("INSERT INTO {$table}(rate,date,currency) VALUES('{$rate}','{$date}','{$currency}')");    // so just insert, its only going to be run once anyway! 
//  } 

     mysql_query("UNLOCK TABLES"); 
     */ 

     echo "1&euro;= ".$currency." ".$rate.", date: ".date('D d m Y',$date)."<br/>"; 
    } 
      $days="";                   // clear days value 
    $prev_date = $date;                  // store the previous date 
} 

echo "<h1>Currencies Saved!</h1>"; 
?> 

그래서 ..... 문제는 두 번째 foreach 루프에 있습니다. foreach ($ XML-> Cube-> Cube-> Cube-> $ _rate)로 스크립트를 실행하면 날짜가 다음과 같습니다. 맞습니다. 누락 된 주말 및 은행 휴일 날짜를 잘 처리하지만 요율 값은 XML의 최신 요율, 즉 오늘날의 값만 참조합니다.

XML의 관련 영역 즉 주어진 날짜의 요율과 같은 데이터를 가져와야합니다.하지만 그렇지 않습니다. 이 문제는 simplexml_load_file에서 발생합니까? 아니면 내 코드에서 어리석은 부분을 놓친 것입니까? 이제 상처를 입기 시작하는 머리가 너무 쉬어 요. 신선한 눈을 가장 환영합니다!

답변

3

$XML->Cube->Cube->Cube 두 번째 루프에서 : $XML->Cube->Cube은 항상 첫 번째 첫 번째 수준의 첫 번째 두 번째 수준 cube을 나타냅니다. cube. 따라서 동일한 요소에서 세 번째 레벨 인 cubes을 반복했습니다. 따라서 오늘 요금 만받습니다. 이해가 되니?

대신 사용해보십시오. html이 아닌 명령 행 출력을위한 코드를 수정했습니다. 주요 변경 사항은 두 번째 foreach 문에 있습니다.

$XML=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml"); 
foreach($XML->Cube->Cube as $time){ 
    echo "----".$time["time"]. "----\n"; 
    foreach($time->Cube as $_rate){ 
     $rate = floatval(str_replace(",", ".", $_rate["rate"])); 
     $currency = addslashes(strtolower($_rate["currency"])); 
     echo "1 euro = ".$currency." ".$rate . "\n"; 
    } 
    echo "------------------\n\n"; 
} 
echo "Done!"; 
+0

Chris, Brilliant! consise 및 포인트 답변. verymuch 감사합니다! 스택 오버플로에있는 모든 멤버 만 포인트와 더 중요한 것은 정확한 답변을 제공 할 수 있습니다! – Nick

+0

질문의 소스 코드가 수정되어 반영되었습니다. – Nick

+0

문제 없습니다. 나는 SimpleXML과도 싸웠다. 감사. –