Yuval200 Posted March 5, 2007 Share Posted March 5, 2007 Hello guys .Well, I have the following issue; I am using the following XML document: <?xml version="1.0" encoding="utf-8"?><posts> <post> <poster>Yuval</poster> <content>Post content</content> </post></posts> Now, I use the SimpleXMLElement class, and it really all works fine, I just don't understand something.When I use the following code: echo $xml[0]->children()->children(); It works two, and it writes "Yuval". My question: how can I access the second element (content)? I have tried several ways but nothing seems to work.Thanks Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 5, 2007 Share Posted March 5, 2007 Hi!You can use it as a class/structure (as shown in the examples here: http://php.net/manual/en/ref.simplexml.php): $poster = $xml->post[0]->poster;$content = $xml->post[0]->content; If you want to display all posts you can do something like this: foreach ($xml->post as $post) { echo '<div class="post>'."\n"; echo '<p>'.$post->content."</p>\n"; echo '<span class="postedby">Posted By:<span class="name">'.$post->poster."</span></span>\n"; echo "</div>\n";} Hope that helped..Good Luck and Don't Panic! Link to comment Share on other sites More sharing options...
Yuval200 Posted March 6, 2007 Author Share Posted March 6, 2007 Yeah, I remember using this way some time ago, forgot about it.. Haha, I'm not that of a beginner, Printing an array in a foreach loop isn't to difficult for me .--Another issue, how do I update existing tags? I have tried the following: echo $xml[0]->post[0]->content;$xml[0]->post[0]->content = "NOT Post content"; But it doesn't seem to work..Thanks Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 6, 2007 Share Posted March 6, 2007 Well, sorry if I hurt your feelings.. ;?)I just like to be clear in my explanations, besides it can be helpfull for some beginner... Link to comment Share on other sites More sharing options...
Yuval200 Posted March 6, 2007 Author Share Posted March 6, 2007 Lol, you haven't hurt anything .Now, if someone could just answer my question Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 6, 2007 Share Posted March 6, 2007 Oh, missed the new question.It should work, it should change the value and keep it until the end of the script or the object is removed.To save it in the file you can use ->asXML (http://php.net/manual/en/function.simplexml-element-asXML.php): $xml->asXML( 'filename.xml' ); Link to comment Share on other sites More sharing options...
Yuval200 Posted March 10, 2007 Author Share Posted March 10, 2007 Sorry, I solved that issue some time ago, now I have a new one with functions; To change the value of a tag, I need to do the following: class xml { public $file; protected $error; function __construct($xmlFile) { $this->error = "<b>Class " . __CLASS__ . ":</b>"; if (!is_array($xmlFile)) die($this->error." \$xmlFile must be entered as an array."); $this->file = array(); foreach($xmlFile as $number => $xml) { $xml = "data/{$xml}"; if (!file_exists($xml)) die($this->error." file {$xml} (<em>number {$number}</em>) doesn't exist."); $this->file[] = new SimpleXMLElement($xml, null, true); //Loads the xml files, one at a time. } } function updateXML($xmlPath, $xmlValue, $attributeName = false) { if (!$attributeName) return $xmlPath = $xmlValue; elseif (!trim($isElement) && trim($attributeName)) { //$this } }}$classxml = new xml(array('posts.xml'));$xml = $classxml->file; Now, I am using the following function: $classxml->updateXML($xml[0]->post[0]->content, "d"); But it doesn't work, Why ?Thanks in advance :} Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 10, 2007 Share Posted March 10, 2007 Hi!The reason it doesn't work is this:You send the value of $xml[0]->post[0]->content to updateXML() (stored in $xmlPath) and then change the value of $xmlPath to $xmlValue, you don't change $xml[0]->post[0]->content.To do you want uo need to use references (http://php.net/manual/en/language.references.php#language.references.whatare) change the declaretion of updateXML() to this: function updateXML( &$xmlPath, $xmlValue, $attributeName = false) {... Then it should work fine (note the ampersand).Hope that helped.Good Luck and Don't Panic! Link to comment Share on other sites More sharing options...
Yuval200 Posted March 10, 2007 Author Share Posted March 10, 2007 Thanks , but it still doesn't work.. the function looks like this now: function updateXML(&$xmlPath, $xmlValue, $attributeName = false) { if (!$attributeName) return $xmlPath = $xmlValue; elseif (trim($attributeName)) { //$this } } Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 10, 2007 Share Posted March 10, 2007 Hm, I don't see a reason to why it doesn't work (how do you know it doesn't work? Do you use echo $xml->asXML(), or what do you do?)Try this:add echo (or var_dump()) in your function to see what it gets: function updateXML(&$xmlPath, $xmlValue, $attributeName = false) { echo 'XMLPath:'.$xmlPath.'; XMLValue:'.$xmlValue.'; AttrName:'.$attributeName."!\n"; if (!$attributeName) return $xmlPath = $xmlValue; elseif (trim($attributeName)) { //$this } } or function updateXML(&$xmlPath, $xmlValue, $attributeName = false) { echo 'XMLPath:'; var_dump($xmlPath) echo '; XMLValue:'; var_dump($xmlValue); echo '; AttrName:'; var_dump($attributeName); echo "!\n"; if (!$attributeName) return $xmlPath = $xmlValue; elseif (trim($attributeName)) { //$this } } What do you get then, do you see what you're expecting or something else... Link to comment Share on other sites More sharing options...
Yuval200 Posted March 11, 2007 Author Share Posted March 11, 2007 updateXML: function updateXML(&$xmlPath, $xmlValue, $attributeName = false) { if (!$attributeName) { echo "XMLPath:\n"; var_dump($xmlPath); echo "\nXMLValue:\n"; var_dump($xmlValue); echo "\nAttrName:\n"; var_dump($attributeName); echo "!\n"; return $xmlPath = $xmlValue; } elseif (trim($attributeName)) { //$this } } It returns the following: XMLPath:object(SimpleXMLElement)#10 (1) { [0]=> string(12) "Post content"}XMLValue:string(1) "d"AttrName:bool(false)! Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 11, 2007 Share Posted March 11, 2007 This may, again, be a long shot, but try to change return $xmlPath = $xmlValue;to return $xmlPath[0] = $xmlValue; or $classxml->updateXML($xml[0]->post[0]->content, "d");to $classxml->updateXML($xml[0]->post[0]->content[0], "d"); I would go with the last one. (To check if it's an array you can use is_array($xml[0]->post[0]->content) ) Link to comment Share on other sites More sharing options...
Yuval200 Posted March 11, 2007 Author Share Posted March 11, 2007 Thanks ALOT man ! I added [0] after $xmlPath and it works great now .Now I have a problem with attributes, I updated my XML document: <?xml version="1.0" encoding="utf-8"?><posts> <post> <poster id="1337">Yuval</poster> <content>Post content</content> </post></posts> I am trying to echo the following line: echo $xml[0]->post[0]->content['id']; Doesn't work, I have tried var_dump: var_dump($xml[0]->post[0]->content['id']);var_dump((string) $xml[0]->post[0]->content['id']); First line returns null, and the second line returns a string with the length of 0. I have tried to chage content['id'] to content[0]['id'] But it still doesn't work.. Can you please help me?Thanks Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 11, 2007 Share Posted March 11, 2007 Well, You don't have an id on content, but you have an id on poster.So if you change it to echo $xml[0]->post[0]->poster['id']; It should work fine.Or you could move the id to post: <?xml version="1.0" encoding="utf-8"?><posts> <post id="1337"> <poster>Yuval</poster> <content>Post content</content> </post></posts> echo $xml[0]->post[0]['id']; Don't Panic! :?) Link to comment Share on other sites More sharing options...
Yuval200 Posted March 11, 2007 Author Share Posted March 11, 2007 Heh, that was a stupid mistake.. THANKS ALOT :)Now, I have a weird error.. This is the function: function updateXML(&$xmlPath, $xmlValue, $attributeName = false) { if (!$attributeName) return $xmlPath[0] = $xmlValue; return $xmlPath[$attributeName] = $xmlValue; } And the code: $classxml->updateXML($xml[0]->post[0]->poster, "66", "id");$classxml->updateXML($xml[0]->post[0]->content, "d");echo $xml[0]->post[0]->poster['id'] . "\n" . $xml[0]->post[0]->content; With the code above it changes the content, but the thing I noticed is when I delete the first line, the value of "id" returns to 1337, and when removing the second line, content value returns to be "Post Content". Why? Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 11, 2007 Share Posted March 11, 2007 Why shouldn't they?As long as you don't save to the file (using $xml->asXML( 'filename.xml' )) that would happen, as it loads in the same structure every time.If you DO save it and still get the same result, it's hard to tell what the problem is. Link to comment Share on other sites More sharing options...
Yuval200 Posted March 12, 2007 Author Share Posted March 12, 2007 So I need to save all I did when I finish working with the XML document? How do I do this? Link to comment Share on other sites More sharing options...
Mr_CHISOL Posted March 12, 2007 Share Posted March 12, 2007 Yes you do need to save it!And (for the third time...) Here's how to do it: $xml->asXML( 'filename.xml' ) :?) Link to comment Share on other sites More sharing options...
Yuval200 Posted March 15, 2007 Author Share Posted March 15, 2007 Oh, sorry, thanks again :)I'm doing fine now XML wise, I only have a small OOP issue. I have read about the __destruct function. As I understood, the function works when the parser finish parsing the code and there is no more HTML to be wrote. Code-wise it works great. class xml { public $file, $error, $xmlfile = array(); function __construct($xmlFile) { $this->error = "<b>Class " . __CLASS__ . ":</b>"; if (!is_array($xmlFile)) die($this->error." \$xmlFile must be entered as an array."); $this->file = array(); foreach($xmlFile as $number => $xml) { $xml = "data/{$xml}"; $this->xmlfile[] = $xml; if (!file_exists($xml)) die($this->error." file {$xml} (<em>number {$number}</em>) doesn't exist."); $this->file[] = new SimpleXMLElement($xml, null, true); //Loads the xml files, one at a time. } return $this->file; } function updateXML(&$xmlPath, $xmlValue, $attributeName = false) { if (!$attributeName) return $xmlPath[0] = $xmlValue; return $xmlPath[$attributeName] = $xmlValue; } function __destruct() { foreach($this->xmlfile as $number => $xml) { if(!$this->file[$number]->asXML($xml)) die($this->error." Could not update file {$xml} (number {$number})."); $this->file[$number]->asXML($xml); die("INDEED"); } }} (just refer to the __destruct function, it's the only thing changed). The interesting part is that when I change the function name to something like __fhfdsdsbfdsa and then call it using $classxml->__dfkmdmbldflbndfalbd() it works great. Why? Should I not use __destruct for this case?Thanks Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now