使用 XML 提取 XML 中的 ECB 汇率时遇到一些问题..有问题的完整源代码

发布于 2024-11-30 06:50:08 字数 4380 浏览 0 评论 0原文

我需要获取内部会计系统的历史汇率参考率列表。

这个问题仅涉及以下代码,如果您发现它有用,请随意使用此代码(当然,一旦我们得到解决最终“问题”的答案。我在代码中包含了数据库结构转储,所有数据库例程已被注释掉,目前仅回显调试数据

数据取自欧洲中央银行 XML,位于 http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml

已修复,如果您需要获取历史汇率列表,请随意使用此代码!将值写入数据库..确保删除回显调试并整理数据库查询

<?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 as 您会发现日期是正确的,它可以很好地处理缺少的周末和银行假日日期,但汇率值仅引用 XML 中的最新汇率,即今天的值。

$_rate),如果您尝试运行该脚本, 从 XML 中的相关区域提取数据,即给定日期的费率...但事实并非如此。这是 simplexml_load_file 中的问题还是我在代码中错过了一些愚蠢的东西?现在头开始疼了,先休息一下。新鲜的眼睛是最受欢迎的!

I need to grab a list of historic Exchange rate reference rates for an internal accounting system.

This question is about the following code only, feel free to use this code if you find it useful (and of course once we get an answer to fix the final "niggle". i have included a DB structure dump in the code, all DB routines are commented out, just echoing debug data for now.

Data is taken from the European Central Bank XML found at http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml

FIXED! Feel free to use this code if you need to pull a list of historic exchange rate values into a DB.. make sure to remove echo debugging and sort out the DB queries

<?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€=  ".$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>";
?>

So..... the problem is in the 2nd foreach loop: foreach($XML->Cube->Cube->Cube as $_rate), if you try running the script you will notice that the dates are right, it handles missing weekend and bank holiday dates well, but the rate values only ever reference the latest rates in the XML, ie todays values.

It should be pulling data from the relevant area in the XML, ie the rates for the given date... but its not. Is this a problem in simplexml_load_file or have I missed somthing stupid in my code? Head starting to hurt now so gonna take a break. Fresh eyes are most welcome!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开雨落又逢春i 2024-12-07 06:50:08

第二个循环中的 $XML->Cube->Cube->Cube$XML->Cube->Cube 始终引用第一个第二个 -第一个第一级多维数据集中的级别多维数据集。因此,您正在迭代同一元素中的第三级多维数据集。因此,您只能获得今天的费率。有道理吗?

试试这个吧。我已将您的代码修改为命令行输出而不是 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!";

$XML->Cube->Cube->Cube in your second loop: $XML->Cube->Cube always refers to the first second-level cube in the first first-level cube. So you were iterating over the third level cubes in that same element. Thus, you got only today's rates. Make sense?

Try this instead. I've modified your code for command-line output rather than html. The only major change is in the second foreach statement...

$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!";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文