2012-01-20 46 views
2

我已經將xml文件導入FTP服務器。這是存儲在位置「/的public_html/ctrackxml /」有一個隨機文件名和格式如下:PHP代碼 - 從Web服務器(/ public_html/ctrackxml)導入xml文件到mysql數據庫

<message type="POSITIONDATA"> 
    <messageid>-1</messageid> 
    <mobile>SNK261GP</mobile> 
    <time>2012/01/20 08:34:45 AM</time> 
    <latitude>-29.8477</latitude> 
    <longitude>30.9554</longitude> 
    <status>Driving</status> 
    <speed>82</speed> 
    <address> near Outer Ring Road (N2); Umkumbaan; in Durban</address> 
    <direction> 
    </direction> 
    <runningodo>1587000</runningodo> 
</message> 

我需要遍歷文件夾中的所有文件和每個文件導入MySQL數據庫表XMLDATA其具有以下結構:

MySQL table

我需要在XML文件的每個標籤被導入到在表中一個單獨的字段。所以每個xml文件都代表一個表項。

從我做的研究看來,我需要使用'LOAD XML LOCAL INFILE'mysql語法,但是我似乎無法讓它直接在mysql中正常工作。

如果你能指出我正確的方向,我將不勝感激。

更新

下面是我甲肝emanaged與其他網站的幫助湊的代碼。 http://www.phpfreaks.com/forums/index.php?topic=244744.0

我測試了phpfreaks的腳本,它的工作原理是100%,但是xml結構是完全不同的。我試圖修改代碼來適應我的XML文件,但我有一些問題,以使其工作。

我的代碼如下,但目前未能ONT他foreach語句:

<?php 

echo "starting <br><br>"; 
//mysql connection 
$con2 = mysql_connect("localhost","dbuser","dbpassword"); 
if (!$con2) { die('Could not connect: ' . mysql_error()); } 
$selectdb = mysql_select_db("dbname", $con2); 
if (!$selectdb) { die('Database not used: ; ' . mysql_error()); } 

echo "connected to DB<br/><br/>"; 

//simplexml load xml file 
$library = simplexml_load_file('http://www.website/ctrackxml/CTO_20120119140006_0000.xml'); 

echo "xml loaded<br/><br/>"; 

//loop through parsed xmlfeed and print output  

foreach ($message->message as $message) {     
printf("messageid: %s\n", $messageid->messageid);     
printf("mobile: %s\n", $mobile->mobile); 
printf("time: %s\n", $time->time); 
printf("latitude: %s\n", $latitude->latitude); 
printf("longitude: %s\n", $longitude->longitude); 
printf("status: %s\n", $status->status); 
printf("speed: %s\n", $speed->speed); 
printf("address: %s\n", $address->address); 
printf("direction: %s\n", $direction->direction); 
printf("runningodo: %s\n", $runningodo->runningodo); 

echo "xml parsed<br/><br/>"; 

//insert into databse      
mysql_query("INSERT INTO xml (messageid, mobile, time,latitude,longitude,status,speed,address,direction,odometer) 
VALUES (\"$messageid->messageid\", \"$mobile->mobile\", \"$time->time\", \"$latitude->latitude\", \"$longitude->longitude\", \"$status->status\", \"$speed->speed\", \"$address->address\", \"$direction->direction\", \"$runningodo->runningodo\")") 
or die(mysql_error()); 

echo "inserted into mysql<br/><br/>"; 

//show updated records    
printf ("Records inserted: %d\n", mysql_affected_rows()); 
} 


//close connection 
mysql_close($con2); 

?> 

感謝一如既往對大家的幫助。

+2

PHP的[SimpleXML](http://us2.php.net/manual/en/book.simplexml.php)可能會成爲這項工作的最佳工具,如果你最終沒有獲得LOAD XML'工作。 – Charles

+0

嗨@Charles,請參閱我的問題的更新?你能幫助我使用這個腳本,目前不符合foreach。謝謝, – Smudger

+1

xml中的根元素是什麼? – 2012-01-20 13:26:19

回答

2
<?php 

ini_set('display_errors','On'); 

echo "starting"; 

//mysql connection 
$con2 = mysql_connect("localhost","dbuser","dbpass"); 
if (!$con2) { 
    die('Could not connect: ' . mysql_error()); 
} 

$selectdb = mysql_select_db("dbname", $con2); 
if (!$selectdb) { 
    die('Database not used: ; ' . mysql_error()); 
} 

echo "connected to DB<br /><br />"; 

// Read filenames in current directory looking for XML files 
$file_arr = array(); 
if ($handle = opendir('.')) { 
    while (false !== ($file = readdir($handle))) { 
     if (($file != ".") && ($file != "..")) { 
      if(substr($file, -4) == ".xml") 
      { 
       array_push($file_arr, $file); 
      } 
     } 
    } 
    closedir($handle); 
} 

// Loop through each XML file in the current directory 
foreach($file_arr as $filename) 
{ 
    //simplexml load xml file 
    $mess = simplexml_load_file($filename); 
    echo "xml loaded<br /><br />"; 

    $messageid = mysql_real_escape_string($mess->messageid); 
    $mobile = mysql_real_escape_string($mess->mobile); 
    $time = mysql_real_escape_string($mess->time); 
    $latitude = mysql_real_escape_string($mess->latitude); 
    $longitude = mysql_real_escape_string($mess->longitude); 
    $status = mysql_real_escape_string($mess->status); 
    $speed = mysql_real_escape_string($mess->speed); 
    $address = mysql_real_escape_string($mess->address); 
    $direction = mysql_real_escape_string($mess->direction); 
    $runningodo = mysql_real_escape_string($mess->runningodo); 

    echo "xml parsed<br /><br />"; 

    //insert into databse      
    mysql_query("INSERT INTO xml (messageid, mobile, time, latitude, longitude, status, speed, address, direction, odometer) 
    VALUES ('$messageid', '$mobile', '$time', '$latitude', '$longitude', '$status', '$speed', '$address', '$direction', '$runningodo')") 
    or die(mysql_error()); 

    echo "inserted into mysql<br /><br />"; 

    //show updated records    
    printf ("Records inserted: %d\n", mysql_affected_rows()); 
} 
//close connection 
mysql_close($con2); 

?> 

上面的代碼應該實現你正在尋找什麼基於規範。如前所述,每個XML文件都有一個XML記錄。

此代碼旨在與XML文件在同一目錄中運行,您可以通過在代碼中編輯opendir命令輕鬆更改此代碼。它將讀取當前工作目錄中的所有XML文件,並將數據放入數據庫。

+0

嗨,利奧我已經嘗試了你的代碼,並不得不修改應用msql bieng depracted在PHP 7中,但是當我運行新代碼時,我得到dbname.xml沒有找到錯誤,每件事情都很好,直到「mysqli_query($ con2,」INSERT INTO xml ('messageid','$ mobile','$ time','$ latitude','$ longitude','$','','',' $ status','$ speed','$ address','$ direction','$ runningodo')「) 或die(mysqli_error($ con2));」任何想法 –

+0

嗨利奧我的錯誤有兩個問題,一個是我應該命名錶xml另一個是沒有對數據庫中的「里程錶」的任何表示感謝 –

3

我最近從事的項目與您所需的項目有一些相似之處。正如Charles建議的那樣,我使用simplexml進行解析。我的任務還需要通過ftp連接到服務器,獲取文件,將它們解壓到目錄等。

我的方法是編寫處理一個文件的腳本,使用simplexml讀取文檔,做一些簡單的轉換並寫入數據到mysql。

然後,我創建了一個簡單的bash腳本包裝器,該包裝器讀取目錄中的所有文件,並將其作爲參數傳遞給我的處理腳本。

如果您發現您的結構足夠接近以允許使用LOAD XML,則根本不需要PHP ......只需bash腳本並重復調用mysql命令行客戶端即可。

php腳本接受文件名作爲命令行參數。當然這是指php CLI。它實際上是一個類,但它像這樣簡單加載文件:

if (file_exists($filename)) { 
     $this->xml = simplexml_load_file($filename); 

從那裏,你可以參考的元素很容易。這個bash腳本是我正在使用的典型代碼,在這裏你將所有xml文件所在的目錄傳遞給它,並且它只是一個一個地處理它們。

#!/bin/bash 
if [ $# -ne 1 ] 
then 
    echo "No directory specified." 
    exit 1 
fi 
DIR="$(cd "$(dirname "$0")" && pwd)" 
FILES="$1"/*.xml 
for f in $FILES 
    do 
    /usr/bin/php -f /path/to/yourscript.php $f 
done 
exit 0 

如果文件是完全按照你描述的話,一旦你做我上面描述的(假定你有一個簡單的類,以方便您的XML變量,那麼你只需要編寫一個INSERT語句和呼叫負載它使用mysql_query函數,實際上我建議你調整模式,以便列類型準確地匹配你爲每列獲得的數據類型,而不是使用數字的varchars,這可以像這樣簡單:

$msg = $this->xml->message; 

$query = "INSERT INTO YOUR TABLE (messageid, mobile...) VALUES ({$msg->message}, '{$msg->mobile}', ...)"; 
// assumes you already made db connection previously 
$result = mysql_query($query); 
if ($result) { 
// inserted ok. 
} else { 
// something wrong, check mysql_error() for specifics 
} 
+0

謝謝@gview。聽到反饋。我正在通過simplexml閱讀,有沒有機會讓我查看和修改工作腳本?因爲我沒有bash的知識,你有一點讓我失望了?如果你能告訴我如何一次處理一個文件,我很樂意用ftp_nlist創建fto循環。謝謝,瑞安 – Smudger

+0

謝謝@gview,這真棒。我肯定會嘗試一下。關於php腳本,它調用的是什麼語法將xml文件導入mysql數據庫,將每個作爲單獨的mysql表字段對待?再次感謝。 R – Smudger

+0

謝謝@gview。真的很欣賞這個輸入。根據你的建議,我會毫不猶豫地繼續嘗試按照你的說法來工作。我只需要做一些閱讀來進一步理解你的例子。在此期間,我編輯了這個問題以顯示我目前正在處理的內容。這隻處理一個文件名,但我不能100%正確。目前該腳本在foreach語句中失敗。再次感謝您的幫助。 Ryan – Smudger

2

瀏覽您的代碼,如下所示:

foreach ($message->message as $message) { 

實際上應該是:

foreach ($library->message as $message) { 

$library包含您的XML對象,因此它應該是你正在訪問一個而不是,到目前爲止,還unitialised $message變量。

$message初始化您的當前代碼實際上會用for循環的每次迭代消除它,因爲它將其子元素分配給自己!

+0

非常感謝。我沒有正確理解這個(simplexml),所以謝謝你的提升。 foreach語句似乎現在正在工作hoever我沒有看到'回聲'xml解析「,所以我不認爲foreach循環完成。有任何想法嗎? – Smudger

1
foreach ($library->message as $mess) {     
    printf("messageid: %s\n", $mess->messageid);     
    printf("mobile: %s\n", $mess->mobile); 
    printf("time: %s\n", $mess->time); 
    printf("latitude: %s\n", $mess->latitude); 
    printf("longitude: %s\n", $mess->longitude); 
    printf("status: %s\n", $mess->status); 
    printf("speed: %s\n", $mess->speed); 
    printf("address: %s\n", $mess->address); 
    printf("direction: %s\n", $mess->direction); 
    printf("runningodo: %s\n", $mess->runningodo); 
} 
+0

謝謝。非常感謝這些建議,我做了以下更改,但正如我在@Treffynnon評論中提到的,我沒有看到「xml解析」的回顯。因此,我不認爲foreach循環正在完成。有什麼建議?謝謝。 R – Smudger

1

在您的輸入中使用mysql_real_escape_string()。 http://se2.php.net/manual/en/function.mysql-real-escape-string.php

它不會解決你目前的問題,但將來的那裏需要逃生字符。

打開display_errors,啓用警告。

嘗試使用foreach循環中的計數器進行調試$ i ++,或者每個循環都會回顯。找出它失敗之前有多遠..

+0

嗨,謝謝你。我的錯誤已打開。 php.ini是display_errors = On – Smudger

+0

嗨,我添加了$ i ++與foreach但它不顯示。謝謝, – Smudger

+0

增加它後,你需要做echo $ i。 – tim

相關問題