PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SimpleXML xpath



senfmensch
12-06-2006, 12:30
hi zusammen,
ich habe nen kleines Prob mit der xpath() Funktion von SimpleXML.

<?xml version="1.0" encoding="UTF-8"?>
<container>
<texte>
<text user="user1">llllasdfasdfeorpqi</text>
<text user="user2">oouzzrrzreorpqi</text>
</texte>
</container>So jetzt wuerde ich gerne über xpath den text von user1 ändern :
<?php
$xml = simplexml_load_file('dateimitobigemxml.xml');
// Jedes ergebnis von der Xpath anfrage wird in dem Array $result als
// Referenz gespeichert. Also $result[0] ist eine Referenz auf $xml->texte->text[0];
$result = $xml->xpath('/texte/text [@user="user1"]');
// $result[0] will ich verändern:
$result[0]['user'] = 'ehemalsUser1'; // Attribute aendern geht
$result[0] = 'neuertext'; // Inahlt ändern funktioniert nicht
echo $xml->asXML(); // Siehe ersten unteren XML-Code
// Das ganze ohne xpath():
$xml->texte->text[0] = 'zweiterneuerText'; // Funktioniert auch
echo $xml->asXML(); // Siehe zweiten unteren XML-Code
?>Erste Ausgabe:
<?xml version="1.0" encoding="UTF-8"?>
<container>
<texte>
<text user="ehemalsUser1">llllasdfasdfeorpqi</text>
<text user="user2">oouzzrrzreorpqi</text>
</texte>
</container>Zweite XML Ausgabe:
<?xml version="1.0" encoding="UTF-8"?>
<container>
<texte>
<text user="ehemalsUser1">zweiterneuerText</text>
<text user="user2">oouzzrrzreorpqi</text>
</texte>
</container>Wie es scheint, wird $result[0] zu einem string umgewandelt und nicht wie ein richtiges SimpleXMLObject behandelt.
Oder mach ich irgendetwas falsch?

Gruss
senfmensch

Romanday
12-06-2006, 18:18
Oder mach ich irgendetwas falsch?

Gruss
senfmensch

Jau,
da wird ja auch ganz wild gecodet.

Für doch mal var_dump(); aus um Geheimnisse zu enträtseln.:D



$result = $xml->xpath('/texte/text [@user="user1"]');
var_dump($result);
// $result[0] will ich verändern:
$result[0]['user'] = 'ehemalsUser1'; // Attribute aendern geht
$result[0] = 'neuertext'; // Inahlt ändern funktioniert nicht

senfmensch
13-06-2006, 08:18
joar hab ich natuerlich schon gemacht ;)
array(1) {
[0]=>
object(SimpleXMLElement)#2 (2) {
["@attributes"]=>
array(1) {
["user"]=>
string(5) "user1"
}
[0]=>
string(18) "llllasdfasdfeorpqi"
}
}$result[0][0] zu setzen bringt aber auch nix :( dann kommt bei asXML(); das raus:
<?xml version="1.0" encoding="UTF-8"?>
<container>
<texte>
<text user="ehemalsUser1">llllasdfasdfeorpqi</text>
<text user="user2">oouzzrrzreorpqi</text>
<text>neuertext</text></texte>
</container>und das ist fast noch schlimmer ;)

Gruss
senfmensch

Romanday
13-06-2006, 11:42
joar hab ich natuerlich schon gemacht ;)
Gruss
senfmensch

Ich kenne die Klasse nicht.
Was sagt den die Doku?
Gibt es dort vielleicht eine Methode WriteAttribut(), SetAttribut() o. AddAttribut?
Zur Not schreibst Du so eine Methode, dann sollte es auf jeden Fall
funktionieren.

Ich würde auch mit $xml-> weitermachen, da dies dein eigentliches
Objekt ist.
Du hast einen externen Array gebildet in dem zusätzlich dein Objekt
gespeichert wurde. Nett aber unnütz.:D

Du kannst den Wert von außen nur überschreiben, wenn du den
Namen der Variable kennst.
Besser ist es aber dafür einer Methode zu verwenden, welche innerhalb
der Klasse den Wert neu setzt. Von außen wird der Methode dann
der String übergeben, wie Du es auch schon bei $xml->xpath(); gemacht hast.

Schau dir mal in der Klasse an, wie @user="user1" gespeichert wurde.
Dann kannst Du mit einer zusätzlichen Methode + $this>variable den
Wert überschreiben.

senfmensch
13-06-2006, 13:44
Ich kenne die Klasse nicht.
Was sagt den die Doku?
Gibt es dort vielleicht eine Methode WriteAttribut(), SetAttribut() o. AddAttribut?
Zur Not schreibst Du so eine Methode, dann sollte es auf jeden Fall
funktionieren.habe leider keine Ahnung von C/C++ drum wirds nicht viel bringen wenn ich die Klasse anschaue :)
Die Funktionen addChild(), addAttribute() gibts, doch existieren meine nodes und attribute ja schon.

Ich würde auch mit $xml-> weitermachen, da dies dein eigentliches
Objekt ist.
Du hast einen externen Array gebildet in dem zusätzlich dein Objekt
gespeichert wurde. Nett aber unnütz.:Ddas return von xpath ist ein Array mit referenzen auf die Nodes des SimpleXML Objects und ist nix nichts zusaeztliches :)
Du kannst den Wert von außen nur überschreiben, wenn du den
Namen der Variable kennst.
Besser ist es aber dafür einer Methode zu verwenden, welche innerhalb
der Klasse den Wert neu setzt. Von außen wird der Methode dann
der String übergeben, wie Du es auch schon bei $xml->xpath(); gemacht hast.xpath() ist nicht von mir geschrieben :) das ist "builtin".
$result[0] ist eine referenz auf $xml->texte->text[0], also kenne ich ja die Variable, nur verhaelt sich das irgendwie anders anders beim speichern :(

Schau dir mal in der Klasse an, wie @user="user1" gespeichert wurde.
Dann kannst Du mit einer zusätzlichen Methode + $this>variable den
Wert überschreiben.wie gesagt die ResultElemente sind Referenzen auf die Nodes von dem SimpleXML object.
$result[0]['user'] = 'neuerUser';
ist das gleiche wie
$xml->texte->text[0]['user'] = 'neuerUser';

die xpath methode macht mir sozusagen:
$result[0] = &$xml->texte->text[0];

drum ist es komisch dass ich nicht einfach
$result[0] = 'neuerString';
machen kann, denn bei $xml->texte->text[0] funktionierts

Gruss
senfmensch

senfmensch
13-06-2006, 14:13
gibt wohl irgendwie ein Problem, wenn ich eine Referenz benutze:
$resultXML = &$xml->texte->text[0];
$resultXML['name'] = 'neuerName'; //funktioniert
$resultXML = 'neuerText'; // funktioniert nicht! GRMLich glaub ich wende mich mal an die Mailingliste :)

undefined
13-06-2006, 14:32
XPath ist zum lesen und nicht zum Schreiben gedacht ;)
Ich würde wenn du Knoten Bearbeiten möchtest folgendes Machen.



$xml = simplexml_load_file('dateimitobigemxml.xml', 'DomDocument' );
$DomElement = $xml->getElementsByName('meineKnoten')->item(0);
.... Ab hier Kannst du mit DOM Arbeiten und nach Herzenslust Manipulieren ...

senfmensch
14-06-2006, 09:54
klar kann ichs mit dom machen :)
aber das verhalten mit der referenz ist doch sehr merkwuerdig und würde mich interessieren wieso das nicht geht.
ich fänds jedenfalls sehr sinnvoll und arbeitserleichternd wenn man die ergebnisse von xpath gleich bearbeiten kann :)

undefined
14-06-2006, 13:51
Noch mal, DOMXPath ist dazu gemacht schnell und Unkomplizirt auf einzelne Elemente zu greifen zu können und nicht zum Bearbeiten. Also ich Arbeite täglich mit DOM und weis jetzt nicht wo du nicht klar kommst. Seit PHP5 hat man sich erheblich an den W3C Xpath angelehnt was einem die Arbeit erheblich erleichtert.

senfmensch
14-06-2006, 14:45
hab ich irgendwo geschrieben, dass ich was mit dom mache ?
ich wunder mich eben nur ueber das verhalten dieser referenz bei nem simplexmlelement