|
|||||||
php SimpleXML check if a child exists
Время создания: 22.07.2018 00:25
Текстовые метки: php simplexml exist node
Раздел: PHP
Запись: Velonski/mytetra-database/master/base/1532201109u4yyoh2g5m/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
A->b->c might exist but c might not exist. How do I check it? php simplexml shareimprove this question edited Jan 22 '15 at 11:39 peter-b 1,31042140 asked Oct 13 '09 at 15:04 An employee 1,96082541 Please select a new answer – Tim Ogilvy Apr 27 '17 at 9:58 add a comment 15 Answers active oldest votes up vote -12 down vote accepted if($A->b->c != null) //c exists If c does not exist, its value will be null (or, to be more precise, it will have no value). Note, however, that for this to work, both A and b need to not be null. Otherwise, PHP will throw an error (I think). shareimprove this answer edited Nov 15 '16 at 15:20 TRiG 6,65243781 answered Oct 13 '09 at 15:17 Pim Jager 26k146492 18 This isn't a great idea. c will be an empty object if the node does not exist, which isn't the same as NULL. – spikyjt Jan 22 '13 at 11:15 4 To add to what @spikyjt said, if node c doesn't exist in $A->b, an empty SimpleXMLElement is returned. The valid instance of SimpleXMLElement is not null; that expression always evaluates true. – Matt Nov 19 '13 at 19:17 add a comment up vote 106 down vote It might be better to wrap this in an isset() if(isset($A->b->c)) { // c exists That way if $A or $A->b don't exist... it doesn't blow up. shareimprove this answer answered Oct 13 '09 at 18:41 null 4,99431826 13 This seemed neater than the other answers, but actually SimpleXMLElement returns and empty SimpleXMLElement object for any requested node that doesn't exist. So the empty() method seems like the best route. – spikyjt Jan 22 '13 at 11:22 also, c may be optional but A and b may be required, so I may actually want to get an exception if they are not defined - easy way to check document's integrity – davka Feb 28 '13 at 10:50 @spikyjt isset() is the best route to check if the node exists. You can use empty() if you need to check whether the node exists AND has something inside it, i.e. between > and < (either text or child nodes). If you need just to check for the existence of the node then empty() won't do. For example, empty() will return you true for this node <b a="zzz"></b> – CITBL Apr 18 '17 at 15:42 1 @CITBL you are correct, empty() is not much use. It is important to be aware however, that if there is no c element, isset($A->c) === false, but $A->c returns an empty SimpleXMLElement. So with $c = $A->c;, then isset($c) === true (i.e. $c !== null even though that might be expected). – spikyjt Apr 18 '17 at 22:14 add a comment up vote 38 down vote SimpleXML always return Object. If there is no child, empty object is returned. if( !empty($a->b)){ var_dump($a->b); } shareimprove this answer answered Mar 17 '11 at 20:03 CedCannes 39732 Apparently this is a feature and not a bug. And it is very important to note this. Accessing a child of the object will create it if it does not exist. – cosmin Apr 25 '13 at 14:50 2 This should be the accepted answer, would have saved me some time and frustration :-) – Niek Klein Kromhof May 24 '16 at 14:09 1 Wrong answer. Because empty() returns true even if the node exists but has no content. For example, in your code sample, if $a contains this: <xml><b a="zzz"/></xml> then empty($a->b) will return true. Therefore that's not a reliable way to check if a node exists. You can use empty() though if you need something inside a node, i.e. between > and <, and not interested in the node without content – CITBL Apr 28 '17 at 20:04 add a comment up vote 7 down vote I solved it by using the children() function and doing a count() on it, ignoring an PHP error if there are no children by putting an @ before the count-call. This is stupid, but it works: $identification = $xml->identification; if (@count($identification->children()) == 0) $identification = $xml->Identification; I hate this... shareimprove this answer edited Sep 13 '11 at 18:09 Jérôme Verstrynge 26.5k60211370 answered Nov 24 '10 at 15:11 scippie 98411331 8 +1 for "I hate this" :) – Ilari Kajaste Dec 19 '13 at 11:03 add a comment up vote 6 down vote Method xpath returns array of matched elements or false if(false !== $A->xpath('b/c')) { ... http://www.php.net/manual/ru/simplexmlelement.xpath.php shareimprove this answer answered Sep 25 '13 at 10:32 user1391077 6911 1 No, the docs indicate it returns FALSE if there's an error, not if the path returned no results. – Brian Mar 14 '17 at 15:24 add a comment up vote 4 down vote After some experimentation, I've discovered that the only reliable method of checking if a node exists is using count($xml->someNode). Here's a test case: https://gist.github.com/Thinkscape/6262156 shareimprove this answer answered Apr 10 '14 at 12:52 Artur Bodera 1,4491518 add a comment up vote 2 down vote If you have PHP 5.3, you can just use $a->count(). Otherwise, scippie's solution using @count($a->children()) works well. I find I don't need the @ but older PHP implementations may need it. shareimprove this answer edited Sep 13 '11 at 18:09 Jérôme Verstrynge 26.5k60211370 answered Mar 23 '11 at 23:05 Alex Matulich 8111 add a comment up vote 2 down vote Using if(isset($A->b){ gave me issues, so I tried if($A->b){ and it worked! shareimprove this answer answered Jun 6 '12 at 12:49 Daydah 297517 2 count and cast to boolean are the two ways that makes sense. Using if as you describe is the shortest way to cast to boolean. – Brilliand Jan 6 '15 at 18:56 add a comment up vote 1 down vote Simply var_dump(count($xml->node)); shareimprove this answer answered Mar 15 '17 at 18:04 Oğuz Can Sertel 425717 add a comment up vote 0 down vote You could try: if($A->b->c && $A->b->c != '') shareimprove this answer edited Sep 13 '11 at 18:09 Jérôme Verstrynge 26.5k60211370 answered Jun 21 '11 at 16:08 jgrund 18112 add a comment up vote 0 down vote Thought I'd share my experience. Running on 5.4 I tried testing with 'isset' and 'empty' but neither worked for me. I ended up using is_null. if(!is_null($xml->scheduler->outterList->innerList)) { //do something } shareimprove this answer answered Aug 2 '13 at 21:29 user857276 6771918 add a comment up vote 0 down vote Name Spaces Be aware that if you are using name spaces in your XML file you will need to include those in your function calls when checking for children otherwise it will return ZERO every time: if ($XMLelement->children($nameSpace,TRUE)->count()){ //do something here } shareimprove this answer answered Oct 1 '14 at 17:26 g-man 544 add a comment up vote 0 down vote The 3 ways I can confirm work in PHP 5.5.23 were using isset() count() or empty() Here is a script to show the results from each: https://gist.github.com/mchelen/306f4f31f21c02cb0c24 shareimprove this answer answered Apr 15 '15 at 18:43 Mike Chelen 31928 add a comment up vote 0 down vote Using xpath: function has_child(\SimpleXMLElement $parent=null, string $xpathToChild) { return isset($parent) && !empty($parent->xpath('('.$xpathToChild.')[1]')); } where $parent is an indirect or direct parent of the child node to check and $xpathToChild is an xpath to the child relative to $parent. ()[1] is because we don't want to select all the child nodes. One is enough. To check if $a->b->c exists: has_child($a,'b/c'); or has_child($a->b,'c'); You can also check for attributes. To check if the node c has the t attribute. has_child($a,'b/c/@t'); shareimprove this answer edited Apr 18 '17 at 16:41 answered Apr 18 '17 at 13:09 CITBL 63221128 add a comment up vote 0 down vote I use a helper function to check if a node is a valid node provided as a parameter in function. private static function isValidNode($node) { return isset($node) && $node instanceof SimpleXMLElement && !empty($node); } Usage example: public function getIdFromNode($node) { if (!self::isValidNode($node)) { return 0; } return (int)$node['id']; } |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|