# XML import zu Mysql



## kollo2411 (9. August 2010)

Hey leute,

hab hier ein problem mit meinem Xml import der zwar soweit läuft, aber nun noch abgeändert werden soll das beim import die geänderten Daten per update in die datenbank geschrieben werden hat da jemand ne Idee****

Hier mal mein Code:

```
if(isset($_POST['xml']))
{
	
 	$dbhost = 'localhost'; 
    $dbuser = 'root'; 
    $dbpass = 'pass'; 
    $dbdata = 'adresse';
    $dbtabelle = $_POST['tabellenname'];
    

    mysql_connect($dbhost,$dbuser,$dbpass) or die(mysql_error());
    mysql_select_db($dbdata) or die(mysql_error());	
    mysql_query("SET names utf8");
   
    
function  Objekt2Array($Objekt)
{
	    $Rueckgabewert = NULL;

	   if(is_array($Objekt))
	   {
	       foreach($Objekt as $Schluessel => $Wert)
	       {
	           $Rueckgabewert[$Schluessel] = Objekt2Array($Wert);
	       }
	    }
	    else
	   {
       $Objektelemente = get_object_vars($Objekt);
 
        if($Objektelemente)
       {
            foreach($Objektelemente as $Schluessel => $Wert)
            {
                $Rueckgabewert[$Schluessel] = Objekt2Array($Wert);
            }
        }
        else
        {
            return strval($Objekt);
        }
    }
 
    return $Rueckgabewert;
}
 
$DateinameXML = "/Daten/fb_servers/adb/Page/test.xml";

 
$objekt = simplexml_load_file($DateinameXML);
$array = Objekt2Array($objekt);
$array = array_values($array);
 
 
// Generierung der Data Modeling Language (DML)
 
for($i = 0, $MySQLSpalten = "", $MySQLWerte = ""; $i < count($array[0]); $i++)
{
    foreach($array[0][$i] as $Schluessel => $Wert)
    {
        $MySQLSpalten .= $Schluessel . ", ";
        $MySQLWerte .= "'" . $Wert . "', ";
    }
 
    $arrMySQLDML[] = "INSERT INTO $dbtabelle (" . substr($MySQLSpalten, 0, -2) . ") VALUES (" .   substr($MySQLWerte, 0, -2) . ");";
 
    $MySQLSpalten = "";
    $MySQLWerte = "";
}
 
// Ausgabe von DML
 
	for($i = 0; $i < count($arrMySQLDML); $i++)
	{
	//echo$arrMySQLDML[$i],"\n";
    mysql_query($arrMySQLDML[$i]);
	} 

    
}
```


----------



## Yaslaw (9. August 2010)

*item:* Bitte den Code formatiert in [PHP]mein Code[/PHP] setzen.
So wie er jetzt da steht kann man das Ding kaum lesen

*item:* Was funktioneirt den nicht?


----------



## kollo2411 (9. August 2010)

Hey danke für den tipp mit der Formatierung,

ja im moment kann ich nur leere Tabellen importieren, aber ich möchte das so machen das wenn die Tabelle gefüllt ist geänderte Daten per update eingetragen werden und neue dran gehängt werden.


----------



## Yaslaw (9. August 2010)

Da hilft MySql

```
INSERT ... ON DUPLICATE KEY UPDATE
```
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html


----------



## kollo2411 (9. August 2010)

Ja hört sich gut an aber kann ich das bei mir einbauen? Oder brauche ich da eine andere Lösung?


----------



## Yaslaw (9. August 2010)

Setze mal die Strings nicht von Hand zusammen sondern über implode() und Arrays und etwa so könnte es am Schluss aussehen (Der Teil ind er For-Schleife)

```
$MySQLSpalten = array();
	$MySQLWerte = array();
	$MySQLUpdate= array();
    foreach($array[0][$i] as $Schluessel => $Wert){
    	$MySQLSpalten[] = $Schluessel;
    	$MySQLWerte[] = "'{$Wert}'";
    	$MySQLUpdate[] = "{$schluessel} = '{$Wert}'";
	}

    $arrMySQLDML[] = "
    	INSERT INTO {$dbtabelle} (". implode(', ', $MySQLSpalten) .") 
    	VALUES (".   implode(',', $MySQLWerte) .")
    	ON DUPLICATE KEY UPDATE". implode(',', $MySQLUpdate) .";";
```

Nachtrag:
Falls das SQL nicht das macht was du willst, hier ein Tutorial zum debugen von MySQL-Queries in Kombination mit PHP
PHP MySQL Debug Queries


----------



## kollo2411 (9. August 2010)

Hab das mal so übernommen mit meiner funktion aber da tut sich nix im moment
Was hat das mit den dreien auf sich ****

```
$MySQLSpalten = array();
    $MySQLWerte = array();
    $MySQLUpdate= array();
```


----------



## Yaslaw (9. August 2010)

Initialisieren als array. zurücksetzen auf ein leeres Array bei jedem Durchgang der for-Schleife.

Um das Problem zu finden solltest du mal debugen und den generierten SQL-Code hier posten. (Anleitung siehe mein letztes Posting)

Nachtrag:
Hab grad gesehen, dass nach dem SQL-Befehl UPDATE noch ein Leerzeichen hin sollte...


----------



## kollo2411 (9. August 2010)

hier die Meldung die nun kommt :

arning: simplexml_load_file(): /Daten/fb_servers/adb/Page/test.xml:33: parser error : Input is not proper UTF-8, indicate encoding ! Bytes: 0xF6 0x72 0x67 0x3C in /Daten/fb_servers/adb/Page/import.php on line 86 Warning: simplexml_load_file(): J?rg in /Daten/fb_servers/adb/Page/import.php on line 86 Warning: simplexml_load_file(): ^ in /Daten/fb_servers/adb/Page/import.php on line 86 Warning: array_values(): The argument should be an array in /Daten/fb_servers/adb/Page/import.php on line 88 Warning: implode(): Invalid arguments passed in /Daten/fb_servers/adb/Page/import.php on line 129 Warning: implode(): Invalid arguments passed in /Daten/fb_servers/adb/Page/import.php on line 130 


```
function  Objekt2Array($Objekt)
{
	    $Rueckgabewert = NULL;

	   if(is_array($Objekt))
	   {
	       foreach($Objekt as $Schluessel => $Wert)
	       {
	           $Rueckgabewert[$Schluessel] = Objekt2Array($Wert);
	       }
	    }
	    else
	   {
       $Objektelemente = get_object_vars($Objekt);
 
        if($Objektelemente)
       {
            foreach($Objektelemente as $Schluessel => $Wert)
            {
                $Rueckgabewert[$Schluessel] = Objekt2Array($Wert);
            }
        }
        else
        {
            return strval($Objekt);
        }
    }
 
    return $Rueckgabewert;
}
 
$DateinameXML = "/Daten/fb_servers/adb/Page/test.xml";

 
$objekt = simplexml_load_file($DateinameXML);
$array = Objekt2Array($objekt);
$array = array_values($array);
	
	$mysqlspalten = array();
	$mysqlwerte = array();
	$mysqlupdate = array();

	for($i = 0, $mysqlspalten = "", $mysqlwerte = ""; $i < count($array[0]); $i++)
	{
		foreach($array[0][$i] as $Schluessel => $Wert)
		{
			$mysqlspalten[] = $Schluessel;
			$mysqlwerte[] = "'{$Wert}'";
			$mysqlupdate[] = "{$Schluessel} = '{$Wert}'";
		}
	}
	$arrmysqldml[] = "INSERT INTO $dbtabelle (". implode(', ', $mysqlspalten) .")
	VALUES (". implode(',', $mysqlwerte) .")
	ON DUPLICATE KEY UPDATE" . implode(',', $mysqlupdate) .";";
	
	for($i = 0; $i < count ($arrmysqldml); $i++)
	{
		mysql_query($arrmysqldml[$i]);
	}
```


----------



## Yaslaw (9. August 2010)

*item:* Da gibts ein Fehler beim Einlesen des XML

*item:* Eine Fehlermeldung über array_values(): Das seh ich in deinem Script noch nicht.

*item:* Es fällt mir schwer dir zu sagen was falsch ist, wenn ich nicht weiss was auf den in den Fehlermeldungen angegebenen Zeilen steht.

*item:* Das SQL zusammensetzen sollte innerhalb der for-Schleife stehen. Ansonsten gibts nur ein INSERT und zwar den letzten.

*Tipp:* PHP-Fehlermeldungen in der HTML-Source-Ansicht anschauen. Es ist meistens lesbarer formatiert.


```
warning: simplexml_load_file(): 
/Daten/fb_servers/adb/Page/test.xml:33: parser error : Input is not proper UTF-8, indicate encoding ! Bytes: 0xF6 0x72 0x67 0x3C
in /Daten/fb_servers/adb/Page/import.php on line 86 Warning: simplexml_load_file(): J?rg in /Daten/fb_servers/adb/Page/import.php
on line 86 Warning: simplexml_load_file(): ^ 
in /Daten/fb_servers/adb/Page/import.php 
on line 86 Warning: array_values(): The argument should be an array in /Daten/fb_servers/adb/Page/import.php 
on line 88 Warning: implode(): Invalid arguments passed 
in /Daten/fb_servers/adb/Page/import.php 
on line 129 Warning: implode(): Invalid arguments passed 
in /Daten/fb_servers/adb/Page/import.php on line 130
```


----------



## kollo2411 (9. August 2010)

Ja den fehler hab ich gelöst, doch er schreibt mir die Daten nicht in in die Datenbank rein und die echo ausgabe sieht so aus:

INSERT INTO importuser (userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel, userID, name, vorname, nachname, titel) VALUES ........ aber warum schreibt der das nich in die tabelle****


----------



## Yaslaw (9. August 2010)

Ich sehs... aber du solltest es selber erlernen *g*

Nimm nun das SQL und teste es mit phhpMyQdmin oder 'Heidi SQL' oder sonst einem DB-Tool aus.
Vergleiche das SQL mit dem was du denkst dass da stehen müsste.

Ein Tipp geb ich dir. Hast du wirklich eine Tabelle mit 10Spalten die den Namen userID haben?


----------



## kollo2411 (9. August 2010)

also  das 10Spalten problem scheint nicht mehr da zu sein aber sonst passiert immer noch nix )-:
was hast du den gesehn? 


```
$mysqlspalten = array();
	$mysqlwerte = array();
	$mysqlupdate = array();

	for($i = 0, $mysqlspalten = "", $mysqlwerte = ""; $i < count($array[0]); $i++)
	{
		foreach($array[0][$i] as $Schluessel => $Wert)
		{
			$mysqlspalten[] = $Schluessel;
			$mysqlwerte[] = "'{$Wert}'";
			$mysqlupdate[] = "{$Schluessel} = '{$Wert}'";
		}
	
	
		$arrmysqldml[] = "INSERT INTO $dbtabelle (". implode(', ', $mysqlspalten) .")
		VALUES (". implode(',', $mysqlwerte) .")
		ON DUPLICATE KEY UPDATE" . implode(',', $mysqlupdate) .";";
		
	}
		
	for($i = 0; $i < count($arrmysqldml); $i++)
	{
		echo $arrmysqldml[$i],"\n";
		mysql_query($arrmysqldml[$i]);	
		
	}
```

So siehts nun aus im mom was ist den mit $mysqlspalten = "" , $mysqlwerte = ""; kann das so bleiben ?


----------



## Yaslaw (9. August 2010)

Du hast zwar nicht alle items umgesetzt, aber etwa so sollte es gehen (ich kanns natürlich nicht testen)

```
for($i = 0; $i < count($array[0]); $i++)
    {
    	$mysqlspalten = array();
	    $mysqlwerte = array();
    	$mysqlupdate = array();
        foreach($array[0][$i] as $Schluessel => $Wert)
        {
            $mysqlspalten[] = $Schluessel;
            $mysqlwerte[] = "'{$Wert}'";
            $mysqlupdate[] = "{$Schluessel} = '{$Wert}'";
        }
    
        $arrmysqldml[] = "INSERT INTO {$dbtabelle} (". implode(', ', $mysqlspalten) .")
        VALUES (". implode(',', $mysqlwerte) .")
        ON DUPLICATE KEY UPDATE SET " . implode(',', $mysqlupdate) .";";
        
    }
        
    for($i = 0; $i < count($arrmysqldml); $i++)
    {
        echo $arrmysqldml[$i],"\n";
        mysql_query($arrmysqldml[$i]);    
        
    }
```

Noch ein Tipp, studiere mal auf php.net den Befehl implode() und mach dich mit Arrays vertrauter - dann würdest du erkennen was falsch war.

Nachtrag:
Hab grad bemerkt, dass ich noch den Befehl SET im Update vergessen habe. Findet man aber mit meinem Tutorial dasi ch weiter oben gepostet habe heraus....


----------



## kollo2411 (9. August 2010)

So hab jetzt noch mal alles so überarbeitet wie in deinem beispiel nun schreibt er mir immer noch nix rein aber hab nun wieder eine SQL Fehler meldung : 

Unknown column 'SETuserID' in 'field list'Übertragung fehlgeschlagen.

Hängt mit dem ON DUPLICATE KEY UPDATE SET zusammen, wenn ich den raus nehme bin ich wieder da wo ich am Anfang war kann dann wieder nur eintragen aber wenn sich was ändert in der datei dann überschreibt der nix


----------



## Yaslaw (9. August 2010)

Die Fehlermeldung ist eigentlich eindeutig. Ich empfehle dir gemäss meinem Tutorial vorzugehen und den UPDATE-Befehl von MySQL mal zu studieren und du wirst den Fehler ganz schnell finden und weisst erst noch wie man Fehler findet....


----------



## kollo2411 (10. August 2010)

Ja hab nun mal dein Tutorial weg genommen und mir auch den Updatebefehl angesehn, aber den Fehler hab ich leider noch nicht wirklich finden können...


----------



## Yaslaw (10. August 2010)

'SETuserID'

Fehlt da nicht ein Leerzeichen? Sollte es nicht heissen '... SET userID ....'
Würdest du das genaue SQL mal studieren solltest du das eigentlich sehen.
Ansonsten wäre es schön, das ausgegebene SQL hier zu posten. Erleichtert ungemein die Hilfestellung


----------



## kollo2411 (10. August 2010)

Ja das leer zeichen hab ich gesehen, aber das war es nicht denn seitdem kommt immer :

Übertragung fehlgeschlagen. Grund: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET (userID = '1',name = 'Sascha',vorname = 'Sascha',nachname = 'Wohlt',tit' at line 3


----------



## Yaslaw (10. August 2010)

'Wohlt',tit' Was ist das?

und zudem:


> Ansonsten wäre es schön, das ausgegebene SQL hier zu posten. Erleichtert ungemein die Hilfestellung





> Ansonsten wäre es schön, das ausgegebene SQL hier zu posten. Erleichtert ungemein die Hilfestellung





> Ansonsten wäre es schön, das ausgegebene SQL hier zu posten. Erleichtert ungemein die Hilfestellung


.. hab gelernt, dass man einigen Leuten alles drei mal sagen muss.....

Nachtrag:
Seit wann gibts beim SET eine Klammer?


----------



## kollo2411 (10. August 2010)

upps klammer hab ich vergessen bleibt aber beim dem selben Fehler und was meinst du mit ausgegebenen SQL? steh da irgendwie auf dem Schlauch denn was ich ausgegeben bekomme :

Übertragung fehlgeschlagen. Grund: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET (userID = '1',name = 'Sascha',vorname = 'Sascha',nachname = 'Wohlt',tit' at line 3 

Und Wohlt is ein nachname aber bei tit sollte eigentlich titel stehen.


----------



## Yaslaw (10. August 2010)

kollo2411 hat gesagt.:


> Ja hab nun mal dein Tutorial weg genommen und mir auch den Updatebefehl angesehn


Da wird dir doch das SQL (Updatebefehl, Query, Abfrage, INSERT ... OR UPDATE-Text, oder wie immer du das Ding nennen willst das an die DB gesendet wird und das in meinem Tutrial mit echo $sql ausgegeben wird) ausgegeben oder wie hast du es angeschaut?
Poste es mal!

Falls du jetzt immer noch nicht weisst, was ich will, geh ich davon aus dass du mein Tutorial doch nicht durchgegangen bist


----------



## kollo2411 (10. August 2010)

Also der Befehl:

```
$arrmysqldml[] = "INSERT INTO $dbtabelle (". implode(', ', $mysqlspalten) .")
		VALUES (". implode(',', $mysqlwerte) .")
		ON DUPLICATE KEY UPDATE SET " . implode(',', $mysqlupdate) .";";
```
print_r ($arrmysqldml);

zeigt mir auf dem Bildschirm:

Array ( [0] => INSERT INTO importuser (userID, name, vorname, nachname, titel) VALUES ('1','Sascha','Sascha','Wohlt','2') ON DUPLICATE KEY UPDATE SET userID = '1',name = 'Sascha',vorname = 'Sascha',nachname = 'Wohlt',titel = '2';
und weiter gehts mit 
 [1] => INSERT INTO importuser (userID, name, vorname, nachname, titel) VALUES ('46','stefan','Stefan','Werde','2') ON DUPLICATE KEY UPDATE SET userID = '46',name = 'stefan',vorname = 'Stefan',nachname = 'Werde',titel = '2';


----------



## Yaslaw (10. August 2010)

```
INSERT INTO importuser (userID, name, vorname, nachname, titel) 
VALUES ('1','Sascha','Sascha','Wohlgemuth','2') 
ON DUPLICATE KEY UPDATE SET 
	userID = '1',
	name = 'Sascha',
	vorname = 'Sascha',
	nachname = 'Wohlt',
	titel = '2';
```

Ev. gehts doch nicht ganz so einfach.
Einer der folgende Punkte könnte scheitern. Du kannst dieses SQL von Hand entsprechend mal anpassen und gegen die DB testen (mittels phpMyAdmin)

*SET auf Key-Feld*
ggf. gibts Probel damit, dass die PrimaryKey-Felder auch gesetzt werden.
Zum testen mal die Zeile userId='1', herauslöschen und testen

*userID/titel ist eine Nummer*
momentan übergeben wir alle Felder als Strings. Das gibt Probleme bei numerischen Feldern. Poste doch mal dein Tabellenaufbau von der Tabelle importuser


Nachtrag:
Wenn du mal das CREATE TABLE - Script der Tabelle importuser hier postest, dann kann ich auch testen....


----------



## kollo2411 (10. August 2010)

Ja also der fehler hängt nur am ON DUPLICATE KEY UPDATE SET, nehm ich das raus schreibt er mir die Daten rein hier mal die Struktur der Tabelle userimport:

Tabellenstruktur für Tabelle importuser:
|Feld|Typ|Null|Standard
|------
|//**userID**//|int(11)|Ja|NULL auto increment
|name|varchar(30)|Ja|
|vorname|varchar(30)|Ja|
|nachname|varchar(30)|Ja|
|titel|int(1)|Ja|0


----------



## Yaslaw (10. August 2010)

So, mal bisschen testen......

Ups, Doku falsch gelesen. in diesem Fall braucht es das Wort SET nicht

Also, lösch das SET nach dem UPDATE


----------



## kollo2411 (10. August 2010)

Vielen dank jetzt klappt es mit dem Update auch, da hätte ich aber auch selbst drauf kommen können!
Naja den Wald vor lauter Bäumen nich gesehn (-:
Aber die tipps hier werden mir sicher noch bei anderen Problemen hilfreich sein!


----------



## Yaslaw (10. August 2010)

kollo2411 hat gesagt.:


> Aber die tipps hier werden mir sicher noch bei anderen Problemen hilfreich sein!


Dann war die Mühe ja nicht umsonst *g*


----------

