PHP Code – импортировать XML-файл с веб-сервера (/ public_html / ctrackxml) в базу данных mysql

У меня есть xml-файлы, которые были импортированы на FTP-сервер. Это сохраняется в местоположении '/ public_html / ctrackxml /' со случайным именем файла и в следующем формате:

<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

Мне нужно, чтобы каждый тэг в XML-файле был импортирован в отдельное поле в таблице. поэтому каждый XML-файл представляет собой одну запись в таблице.

Из исследования, которое я сделал, похоже, что мне нужно использовать синтаксис mysql LOAD XML LOCAL INFILE, но я не могу заставить его правильно работать непосредственно в mysql.

Если бы вы могли указать мне в правильном направлении, я был бы очень признателен.

Обновить

ниже приведен код, который я получил, чтобы очистить его вместе с помощью другого веб-сайта. http://www.phpfreaks.com/forums/index.php?topic=244744.0

Я протестировал скрипт из phpfreaks, и он работает на 100%, но структура xml совсем другая. Я попытался изменить код на набор моего xml-файла, но у меня есть некоторые проблемы, чтобы заставить это работать.

мой код выглядит следующим образом, но в настоящее время не выполняется его утверждение 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); ?> 

Спасибо, как всегда, всем за помощь.

 <?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 в текущем рабочем каталоге и помещать данные в базу данных.

Недавно я работал над проектом, который имеет некоторое сходство с тем, что вам нужно. Как предложил Чарльз, я использовал симплекс для синтаксического анализа. Моя задача также требовала подключения через ftp к серверу, получения файлов, распаковки их в каталоге и т. Д.

Мой подход заключался в написании сценария, который обрабатывает один файл, использует simplexml для чтения документа, выполняет некоторые простые преобразования и записывает данные в mysql.

Затем я создал простую оболочку сценария bash, которая считывает все файлы в каталоге и для каждого из них передает его в качестве параметра для моего сценария обработки.

Если вы обнаружили, что ваша структура достаточно близка к тому, чтобы использовать LOAD XML, вам вообще не понадобится PHP … просто скрипт bash и повторные вызовы для клиента командной строки mysql.

PHP-скрипт принимает имя файла как параметр командной строки. Конечно, это относится к CLI php. Это на самом деле класс, но его так же просто, как загрузить файл:

 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. 'd действительно рекомендую вам настроить схему таким образом, чтобы типы столбцов точно соответствовали типу данных, которые вы получаете для каждого столбца, вместо того, чтобы иметь 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 } 

Просмотр кода выглядит следующим образом:

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

должно быть фактически:

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

$library содержит ваш XML-объект, поэтому он должен быть тем, к которому вы обращаетесь, а не только унифицированной переменной $message .

Если бы $message инициализировался, ваш текущий код действительно уничтожил бы каждую итерацию цикла for, потому что он сам присваивает свой дочерний элемент!

 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); } 

Используйте mysql_real_escape_string () на вашем входе. http://se2.php.net/manual/en/function.mysql-real-escape-string.php

Он не решит вашу текущую проблему, а будущие, где нужны символы эвакуации.

Включите display_errors, включите предупреждения.

Попробуйте отладить с помощью счетчика в цикле foreach $ i ++ или эхо каждого цикла. узнайте, как далеко он проходит до сбоя ..