这是一个原始的ofx文件,因为它来自m银行(不用担心,没有什么敏感,我切断了所有交易的中间部分)
开放式金融交易所(OFX)是一个 用于交换的数据流格式 进化的财务信息 来自微软的Open Financial 连通性(OFC)和Intuit的开放性 交换文件格式。
现在我需要解析这个。我已经看到了question,但这不是重复,因为我对如何做到感兴趣。
我相信我可以找出一些聪明的正则表达式来完成这项工作,但这很难看并且容易出错(如果格式发生变化,某些字段可能会丢失,格式化/白色空间不同等等等等。 。)
OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0
<SEVERITY>INFO
</STATUS>
<DTSERVER>20110420000000[+1:CET]
<LANGUAGE>ENG
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>1
<STATUS>
<CODE>0
<SEVERITY>INFO
</STATUS>
<STMTRS>
<CURDEF>EUR
<BANKACCTFROM>
<BANKID>20404
<ACCTID>02608983629
<ACCTTYPE>CHECKING
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20110207
<DTEND>20110419
<STMTTRN>
<TRNTYPE>XFER
<DTPOSTED>20110205000000[+1:CET]
<TRNAMT>-6.12
<FITID>C74BD430D5FF2521
<NAME>unbekannt
<MEMO>BILLA DANKT 1265P K2 05.02.UM 17.49
</STMTTRN>
<STMTTRN>
<TRNTYPE>XFER
<DTPOSTED>20110207000000[+1:CET]
<TRNAMT>-10.00
<FITID>C74BE0F90A657901
<NAME>unbekannt
<MEMO>AUTOMAT 13177 KARTE2 07.02.UM 10:22
</STMTTRN>
............................. goes on like this ........................
<STMTTRN>
<TRNTYPE>XFER
<DTPOSTED>20110418000000[+1:CET]
<TRNAMT>-9.45
<FITID>C7A5071492D14D29
<NAME>unbekannt
<MEMO>HOFER DANKT 0408P K2 18.04.UM 18.47
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>1992.29
<DTASOF>20110420000000[+1:CET]
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>
我目前使用此代码可以获得所需的结果:
<?
$files = array();
$files[] = '***_2011001.ofx';
$files[] = '***_2011002.ofx';
$files[] = '***_2011003.ofx';
system('touch file.csv && chmod 777 file.csv');
$fp = fopen('file.csv', 'w');
foreach($files as $file) {
echo $file."...\n";
$content = file_get_contents($file);
$content = str_replace("\n","",$content);
$content = str_replace(" ","",$content);
$regex = '|<STMTTRN><TRNTYPE>(.+?)<DTPOSTED>(.+?)<TRNAMT>(.+?)<FITID>(.+?)<NAME>(.+?)<MEMO>(.+?)</STMTTRN>|';
echo preg_match_all($regex,$content,$matches,PREG_SET_ORDER)." matches... \n";
foreach($matches as $match) {
echo ".";
array_shift($match);
fputcsv($fp, $match);
}
echo "\n";
}
echo "done.\n";
fclose($fp);
这真的很丑,如果这是一个有效的xml文件,我个人会为此自杀,但如何做得更好?
答案 0 :(得分:5)
考虑到该文件不是XML 甚至SGML ,您的代码似乎很好。你唯一能做的就是尝试制作一个更通用的SAX解析器。也就是说,您只需一次一个块地输入输入流(其中块可以是任何内容,例如一行或简单地设置一定数量的字符)。然后,每次遇到<ELEMENT>
时调用回调函数。您甚至可以像构建解析器类一样幻想,您可以在其中注册侦听特定元素的回调函数。
它会更通用而且不那么“丑陋”(对于某些“丑陋”的定义)但是要维护的代码会更多。如果你需要解析这个文件格式(或者在很多不同的版本中),那么很高兴并且很高兴。如果您发布的代码是您执行此操作的唯一位置,那么只需KISS。
答案 1 :(得分:0)
// Load Data String
$str = file_get_contents($fLoc);
$MArr = array(); // Final assembled master array
// Fetch all transactions
preg_match_all("/<STMTTRN>(.*)<\/STMTTRN>/msU",$str,$m);
if ( !empty($m[1]) ) {
$recArr = $m[1]; unset($str,$m);
// Parse each transaction record
foreach ( $recArr as $i => $str ) {
$_arr = array();
preg_match_all("/(^\s*<(?'key'.*)>(?'val'.*)\s*$)/m",$str,$m);
foreach ( $m["key"] as $i => $key ) {
$_arr[$key] = trim($m["val"][$i]); // Reassemble array key => val
}
array_push($MArr,$_arr);
}
}
print_r($MArr);
答案 2 :(得分:0)
use Google\Cloud\Storage\StorageClient;
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;
use Google_Client;
use Google_Service_Storage;
require '/vendor/autoload.php';
$storage = new StorageClient([
'projectId' => 'project_id'
]);
$bucket = $storage->bucket('bucketname.domain.com');
$client = new Google_Client();
$client->setApplicationName("API_Cloud_Storage");
$client->useApplicationDefaultCredentials();
$client->setScopes(["https://www.googleapis.com/auth/cloud-platform"]);
$service = new Google_Service_Storage($client);
$object = $service->objects->get($bucket, $storage);
$request = new Google_Http_Request($object->getMediaLink());
$response = $client->getAuth()->authenticatedRequest($request);
$body = $response->getResponseBody();
print_r($body);