Jerred121 Posted November 3, 2010 Share Posted November 3, 2010 So I'm getting a "Notice: Trying to get property of non-object in" error when I'm trying to pull data from a xml. I have a complete xml that has all of the potential node that it could ever have and it loads up fine -no errors, but when I load a different xml that doesn't have all of the possible nodes it returns this error several times here is a sample of my code: $source = 'TestFile.xml'; $xml = new SimpleXMLElement($source,null,true); $result = mysql_query("SELECT * FROM tblvalues") or die(mysql_error()); //Return the table row by row while($row = mysql_fetch_array($result)) { $curblk = substr($row['fldelement'],0,3); switch ($row['fldelement']){ case "E06_04": case "E06_05": case "E06_07": case "E06_08": $cursub = $curblk."_04_0"; $xmlVal = $xml->Header->Record->$curblk->$cursub->$row['fldelement']; //grab value from xml break; ... ... ... // the cases go on for a while... ... case "E07_05": case "E07_06": case "E07_07": case "E07_08": $cursub = $curblk."_03_0"; $cursub2 = $curblk."_05_0"; $xmlVal = $xml->Header->Record->$curblk->$cursub->$cursub2->$row['fldelement']; //this is the line that the error points to break; ... ... ... And here is the sample of the xml that returns the error: <E07> <E07_01>-20</E07_01> <E07_02>0</E07_02> <E07_15>-25</E07_15> <E07_16>-25</E07_16> <E07_17>-25</E07_17> <E07_18_0> <E07_18_01> <E07_18>-20</E07_18> <E07_19>-20</E07_19> <E07_20>-20</E07_20> </E07_18_01> .... .... .... The obvious problem (to me) is that my code is trying to return a value from a nonexistent xml node, for example: $xmlVal = $xml->Header->Record->$curblk->$cursub->$cursub2->$row['fldelement']; is looking for: $xmlVal = $xml->Header->Record->E07->E07_03_0->E07_05_0->E07_05 Ok, I get that, so how do I rewrite this so it's not blowing up on something so simple? Quick notes: -This same code works for a more complete xml -Rewriting the xmls is not an option as I have no control over those Edit: Almost forgot, thanks! Quote Link to comment Share on other sites More sharing options...
ignace Posted November 3, 2010 Share Posted November 3, 2010 property_exists Quote Link to comment Share on other sites More sharing options...
Jerred121 Posted November 3, 2010 Author Share Posted November 3, 2010 Even though I'm a noob, I'm still a little embarrassed to ask this... Where/how would i apply the property_exists() function? I've read up on it and from what I understand it returns either true or false but not the value... Would i have to create a function to apply this check? If so could I get and example? I've looked around but I haven't found anything that really applies or at least I simply don't understand. Basically what I want is, if the node is there - return its value, if not - I don't care as long as it isn't an error that will break my page. Quote Link to comment Share on other sites More sharing options...
Jerred121 Posted November 4, 2010 Author Share Posted November 4, 2010 nm, I got it figured out, kinda... I didn't use the property_exists(), rather I used the isset... I still a noob so I have a hard time understanding the uses of of some of the functions. Anyways, here is what I did: $xmlVal = isset($xml->Header->Record->$curblk->$cursub->$cursub2->$row['fldelement']) ? $xml->Header->Record->$curblk->$cursub->$cursub2->$row['fldelement'] : $defualtVal; If it's there, it grabs it, if not you get $defualtVal - most importantly not error! Thank for the previous suggestion ignace, even though I didn't use it, it lead me down the right path! Quote Link to comment Share on other sites More sharing options...
ignace Posted November 4, 2010 Share Posted November 4, 2010 In the case of SimpleXML you would have been able to omit the error's (and future error's) if you used a Proxy or wrapper, like: class SimpleXMLElementWrapper implements ArrayAccess { private $simpleXML; function __construct(SimpleXMLElement $simplexml = null) { $this->simpleXML = $simpleXML; } function __get($offset) { if($this->simpleXML && property_exists($offset, $this->simpleXML)) { $value = $this->simpleXML->$offset; if($value instanceof SimpleXMLElement) { return new self($value); } else { return $value; } } return new self(); } function __call($method, $args) { if($this->simpleXML && method_exists($method, $this->simpleXML)) { return call_user_method_array(array($this->simpleXML, $method), $args); } return array(); } function __toString() { return ''.$this->simpleXML; } } This is a mere example that is not guaranteed to work but shows you how you can omit the nasty exceptions SimpleXML throws for your current and future projects. A usage example would be: $simplexml = new SimpleXMLElementWrapper(new SimpleXMLElement('file.xml')); $simplexml->foo->bar->baz; Although foo bar and baz don't exist it won't throw any exceptions. It should be noted that it's not advised to use this code everytime you use SimpleXMLElement just to omit the problems you can encounter because it makes your code impossible to debug although you could resolve this by passing an extra paramter to SimpleXMLElementWrapper ($throwException) that changes wether or not it shall throw an exception when it can't find an offset. I'm telling you this because for a current project I had to run through an XML that may or may not contain some tags and instead of writing a bunch of isset() statements I wrote a wrapper that returned an empty string instead. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.