Jump to content

PHP Issue With XML..


Yuval200

Recommended Posts

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...