SimpleXML-Element löschen
Christian
- php
Hallo,
ich möchte ein XML-Element löschen. Die XML sieht so aus:
<colors>
<color>
<name>Orange</name>
<ton1>Rot</ton1>
<ton2>Gelb</ton2>
</color>
<color>
<name>Braun</name>
<ton1>Rot</ton1>
<ton2>Grün</ton2>
</color>
</colors>
Ich geh folgendermaßen vor
// Array durchlaufen so oft es 'color' gibt (klappt!)
foreach($xml->xpath('color') as $color){
// Wenn Rot in Ton1 auftaucht (wird gefunden!)
if($color->ton1 == 'Rot')
// lösche die Farbe/den Schlüssel im Array (klappt nicht)
$color->parentNode->removeChild(color);
}
Es läuft so lange wie gewollt, bis ich versuche den Schlüssel zu löschen.
Wie müsste ich es richtig machen? Unter SimpleXML finde ich gar nichts über das Löschen einzelner Elemente.
Danke, Christian
Es läuft so lange wie gewollt, bis ich versuche den Schlüssel zu löschen.
Wie müsste ich es richtig machen? Unter SimpleXML finde ich gar nichts über das Löschen einzelner Elemente.
SimpleXML wandelt das XML doch in ein Objekt um.
Was spricht gegen
unset(element);
Grüß
Hallo Matt!
SimpleXML wandelt das XML doch in ein Objekt um.
Was spricht gegen
unset(element);
Danke, das funktioniert wohl.
Wenn ich jetzt aber weiter gehe:
$xml_data = '<?PHP
$xmlstr = <<<XML
'.$xml->asXML().'
XML;
?>';
$handle = fopen($xml_file, "w");
flock($handle, LOCK_EX);
fwrite($handle, $xml_data);
flock($handle, LOCK_UN);
ist in meiner XML nichts gelöscht. hm
Im Code des Ausgangsposts habe ich nur $color->parentNode->removeChild(color); durch unset($color); ersetzt.
Danke für deine Hilfe!
Christian
Hallo nochmal!
> $handle = fopen($xml_file, "w");
> flock($handle, LOCK_EX);
Hier steht noch ein: ftruncate($handle, 0);
fwrite($handle, $xml_data);
flock($handle, LOCK_UN);
Danke!
Christian
Schon wieder hallo :|
Das mit dem unset() geht doch nicht.
Ich hab mir nach dem unset mal das Array $xml mit print_r() ausgeben lassen und das Element ist immernoch vorhanden :(
Danke uns Sorry für die 3 Posts nacheinander.
Christian
Hallo zum hoffentlich letzten mal...
SimpleXML wandelt das XML doch in ein Objekt um.
Was spricht gegen
unset(element);
Ok, es funktioniert doch irgendwie mit unset().
Ich habe jetzt unset($xml->color);
Wenn ich jetzt aber Grün löschen will, werden auch alle anderen Farben die kein Grün enthalten gelöscht.
Kann ich beim Array-Durchlauf irgendwie den aktuellen Knoten ermitteln um nur den zu löschen?
Danke!
Christian
Hallo,
Kann ich beim Array-Durchlauf irgendwie den aktuellen Knoten ermitteln um nur den zu löschen?
Ich verstehe deine Frage nicht. Zitat aus deinem Code:
// Array durchlaufen so oft es 'color' gibt (klappt!)
foreach($xml->xpath('color') as $color){
Der aktuelle Knoten ist da $color - oder meinst du was anderes?
Mathias
Hallo,
// Array durchlaufen so oft es 'color' gibt (klappt!)
foreach($xml->xpath('color') as $color){Der aktuelle Knoten ist da $color - oder meinst du was anderes?
Nein,ich meine das was du sagst.
Den Knoten an dessen Position die Schleife ist und der Grün als Element hat soll gelöscht werden. Also sowas wie current($color) oder $color[this] oder halt irgendwas mit removeChild(). Ich find aber keinen Ansatz dazu.
Christian
Hallo,
try this:
<?php
error_reporting(E_ALL | E_STRICT);
header('Content-Type: text/plain');
$xmlstr = '<colors>
<color>
<name>Orange</name>
<ton1>Rot</ton1>
<ton2>Gelb</ton2>
</color>
<color>
<name>Braun</name>
<ton1>Rot</ton1>
<ton2>Gruen</ton2>
</color>
</colors>';
$xml = new SimpleXMLElement($xmlstr);
foreach($xml->xpath('color') as $color){
if ($color->ton1 == 'Rot') {
unset($color[0]);
}
}
echo($xml->asXML());
?>
Mathias
Hallo,
try this:
<?php
error_reporting(E_ALL | E_STRICT);
header('Content-Type: text/plain');
$xml = new SimpleXMLElement($xmlstr);foreach($xml->xpath('color') as $color){
if ($color->ton1 == 'Rot') {
unset($color[0]);
}
}echo($xml->asXML());
?>
Ausser ein paar Notice-Meldungen "Undefined variable:(...)" kommt kein Fehler,
das Element wird aber auch nicht gelöscht.
echo($xml->asXML()); zeigt mir genau das Element an welches ich löschen will.
Danke!
Christian
Hallo,
Ausser ein paar Notice-Meldungen "Undefined variable:(...)" kommt kein Fehler
Und was steht in den Meldungen und was steht im Code, der diese Meldungen ausführt?
Mein Beispielcode funktioniert hier (5.2.4) fehlerfrei und wie gewünscht.
Mathias
Hallo,
Ausser ein paar Notice-Meldungen "Undefined variable:(...)" kommt kein Fehler
Und was steht in den Meldungen und was steht im Code, der diese Meldungen ausführt?
Nichts von Bedeutung. Ganz einfache Kontrollvariablen die mit diesem Skript überhaupt nichts zu tun haben weil sie erst wesentlich später behandelt werden. z.B. $error_color = '1'; (wenn man eine abfrage startet, es die farbe aber nicht gibt)
Also erstmal muss ich mich schon wieder korrigieren.
unset($user[0]); löscht gar nichts.
unset($xml->user[0]); löscht das erste, nicht das relevante Element.
Und laut PHP.net müsste es doch auch
if((string) $color->ton2 == 'Grün')
^^^^^^^^
heißen oder?
Mein Beispielcode funktioniert hier (5.2.4) fehlerfrei und wie gewünscht.
'PHP Version 5.2.0-8+etch10' steht bei mir ganz oben fett wenn ich phpinfo() aufrufe. Mag es an der Version liegen? Bei mir tut sich nämlich nichts.
Ich hab hier jetzt stehn
$xml = new SimpleXMLElement($xmlstr);
foreach($xml->xpath('color') as $color){
if($color->ton2 == 'Gruen'){
unset($user[0]);
}
}
echo($xml->asXML());
In der XML-Datei steht jetzt auch mal 'Gruen' statt 'Grün' zur Sicherheit.
Das Element wird auch gefunden, das habe ich mir ausgeben lassen.
Das echo($xml->asXML()); zeigt mir aber alles an, es wurde nichts gelöscht.
Danke für deine Mühe!
Christian
Hallo,
Ich hab hier jetzt stehn
~~~php
$xml = new SimpleXMLElement($xmlstr);
foreach($xml->xpath('color') as $color){
if($color->ton2 == 'Gruen'){
unset($user[0]);
}
}
echo($xml->asXML());
Wo bekommst du plötzlich $user her?! Was hat $user damit zu tun?
Sorry, aber je mehr du hier postest, desto weniger verstehe ich, was du vorhast und was dein Problem ist.
Mach doch bitte mal locker: Stelle uns den gesamten relevanten Code zur Verfügung, das XML vorher und das XML, wie du es haben willst.
Bitte versuche auch mal, mein Beispiel auszuführen, zu verstehen und, wenn es deine Aufgabe nicht erfüllt, davon ausgehend weiterzuarbeiten.
> In der XML-Datei steht jetzt auch mal 'Gruen' statt 'Grün' zur Sicherheit.
Das hatte ich nur gemacht, weil ich meine Testdatei nicht in UTF-8 abgespeichert hatte.
Mathias
--
[SELFHTML aktuell Weblog](http://aktuell.de.selfhtml.org/weblog/)
Hallo Mathias!
Wo bekommst du plötzlich $user her?! Was hat $user damit zu tun?
Sorry, das kommt noch aus dem original Skript woher ich den Code habe.
Mach doch bitte mal locker: Stelle uns den gesamten relevanten Code zur Verfügung, das XML vorher und das XML, wie du es haben willst.
Sorry, ich verzweifel langsam daran. Je mehr ich probiere desto weniger Überblick hab ich grad noch.
Hier die XML colors.php (nach dem Beispiel von PHP.net):
<?PHP
$xmlstr = <<<XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<colors>
<color>
<name>Orange</name>
<ton1>Rot</ton1>
<ton2>Gelb</ton2>
</color>
<color>
<name>Braun</name>
<ton1>Rot</ton1>
<ton2>Gruen</ton2>
</color>
</colors>
XML;
?>
Heraus kommen soll:
<?PHP
$xmlstr = <<<XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<colors>
<color>
<name>Orange</name>
<ton1>Rot</ton1>
<ton2>Gelb</ton2>
</color>
</colors>
XML;
?>
Hier der PHP Code der das bewerkstelligen soll:
// alle Fehler anzeigen
error_reporting(E_ALL | E_STRICT);
// Dokument als Textdokument anzeigen
header('Content-Type: text/plain');
// XML-Datei 'laden'
include('colors.php');
// XML zu Array
$xml = new SimpleXMLElement($xmlstr);
// Array durchlaufen solange es color-Elemente gibt und Element an $color übergeben
foreach($xml->xpath('color') as $color){
// Wenn Kind-Element ton2 'Gruen' ist
if($color->ton2 == 'Gruen'){
// lösche Element (funktioniert nicht)
unset($color[0]);
// sonst tue nichts
}
// Schleife beenden
}
// gib XML Daten aus
echo($xml->asXML());
// erstelle neuen Inhalt von colors.php
$xml_data = '<?PHP
$xmlstr = <<<XML
'.$xml->asXML().'
XML;
?>';
// schreibe neue Datei
$handle = fopen($login_file, "w");
flock($handle, LOCK_EX);
ftruncate($handle, 0);
fwrite($handle, $xml_data);
flock($handle, LOCK_UN);
Das ist jetzt genau der Code, der ausgeführt wird.
Alle Variablen, Arrays und Werte stehen hier jetzt genau so wie bei mir.
Es tut sich aber rein gar nichts, als ob das unset() ignoriert würde.
Christian
Jetzt stimmt alles bis auf den Namen weil ich eine Sockenpuppe bin :)
Christian
Hallo,
dieses Script gibt bei mir folgendes aus:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<colors>
<color>
<name>Orange</name>
<ton1>Rot</ton1>
<ton2>Gelb</ton2>
</color>
</colors>
Diesmal PHP 5.2.5.
Ich denke mal, es handelt sich um einen PHP-Bug.
Wie auch immer, hatte ich erwähnt, dass ich für solche Operationen nicht SimpleXML nehmen würde, weil es für so etwas gar nicht vorgesehen ist? Nimm für Schreiboperationen lieber W3C DOM, da ist PHP 5.2.0 garantiert ausreichend.
Mathias
Hallo Mathias!
Ich habe einen Teil des Scripts jetzt wie folgt umgeschrieben:
// Bedingung zum löschen festlegen
$element = 'ton1';
$wert = 'Rot';
// XML in Array packen
$xml = new SimpleXMLElement($xmlstr);
// Arrayindex auf 0 setzen und
$i = '0';
// Array durchlaufen solange es color-Elemente gibt und Elemente an $color übergeben
foreach($xml->xpath('color') as $color){
// Wenn Kind-Element $element den Wert $wert besitzt
if($color->$element == $wert){
// lösche Element mit aktuellem index
if(count($xml) == '1'){
unset($xml->color);
}else{
unset($xml->color[$i]);
}
// sonst tue nichts
}
// erhöhe Arrayindex
$i++;
// Schleife beenden
}
Das funktioniert soweit endlich prima bis auf den Umstand, dass die Elemente offenbar nur nacheinander gelöscht werden und nicht in einem Rutsch.
Danke!
Christian
Hallo schon wieder! :(
<?php
foreach($xml->xpath('color') as $color){
if ($color->ton1 == 'Grün') { // Rot durch Grün ersetzt
unset($color[0]);
}
}echo($xml->asXML());
?>
Sorry, es wird das erste Element gelöscht, nicht das welches Grün enthält.
(Rot durch Grün ersetzen)
> echo($xml->asXML()); zeigt mir genau das Element an welches ich löschen will.
Stimmt zwar, aber ich glaub deswegen, weil ja das erste gelöscht wurde und es sonst nichts zum anzeigen gibt.
Christian
Hellihello Matthias,
try this:
<?php
error_reporting(E_ALL | E_STRICT);
header('Content-Type: text/plain');$xmlstr = '<colors>
<color>
<name>Orange</name>
<ton1>Rot</ton1>
<ton2>Gelb</ton2>
</color>
<color>
<name>Braun</name>
<ton1>Rot</ton1>
<ton2>Gruen</ton2>
</color>
</colors>';$xml = new SimpleXMLElement($xmlstr);
foreach($xml->xpath('color') as $color){
if ($color->ton1 == 'Rot') {
unset($color[0]);
}
}echo($xml->asXML());
?>
Warum funktioniert das? echo $color->asXML() funktioniert bei mir genauso wie echo $color[0]->asXML(). demnach funktioniert $color ja wie ein zwitter aus objekt und array.
Dank und Gruß,
[frankx](http://community.de.selfhtml.org/visitenkarten/view.php?key=82)
--
[tryin to](http://sauer-ernst.de) [multitain](http://multitain.de) - Globus = Planet != Welt