php SimpleXML проверить, если ребенок существует
A->b->c
могут существовать, но c
может и не существовать. Как мне это проверить?
15 ответов:
if($A->b->c != null) //c exists
если
c
не существует, его значение будетnull
(или, если быть более точным, это не будет иметь никакого значения). Обратите внимание, однако, что для этого нужно работать, какA
иb
не должно бытьnull
. В противном случае PHP выдаст ошибку (я думаю).
может быть, лучше обернуть в
isset()
if(isset($A->b->c)) { // c exists
таким образом, если
$A
или$A->b
не существует... он не взрывается.
SimpleXML всегда возвращает объект. Если дочернего объекта нет, возвращается пустой объект.
if( !empty($a->b)){ var_dump($a->b); }
после некоторых экспериментов я обнаружил, что единственным надежным методом проверки наличия узла является использование
count($xml->someNode)
.вот тестовый случай:https://gist.github.com/Thinkscape/6262156
Если у вас есть php 5.3, вы можете просто использовать
$a->count()
. В противном случае, решение scippie с помощью@count($a->children())
работает хорошо. Я считаю, что мне не нужен @ , но более старые реализации PHP могут понадобиться.
думал, что поделюсь своим опытом. Запуск на 5.4 я попытался протестировать с помощью "isset" и "empty", но ни один из них не работал для меня. Я в конечном итоге с помощью переменной is_null.
if(!is_null($xml->scheduler->outterList->innerList)) { //do something }
Пространства Имен
имейте в виду, что если вы используете пространства имен в XML-файле, вам нужно будет включить их в вызовы функций при проверке детей, иначе он будет возвращать ноль каждый раз:
if ($XMLelement->children($nameSpace,TRUE)->count()){ //do something here }
3 способа, которыми я могу подтвердить работу в PHP 5.5.23, использовали
isset()
count()
илиempty()
вот скрипт, чтобы показать результаты от каждого:
использование xpath:
function has_child(\SimpleXMLElement $parent=null, string $xpathToChild) { return isset($parent) && !empty($parent->xpath('('.$xpathToChild.')[1]')); }
здесь
$parent
является косвенным или прямым родителем дочернего узла для проверки и$xpathToChild
является xpath для ребенка относительно$parent
.
()[1]
потому что мы не хотим выбрать все дочерние узлы. Одного достаточно.чтобы проверить, существует ли $a->b->c:
has_child($a,'b/c');
илиhas_child($a->b,'c');
вы также можете проверить атрибутами. Чтобы проверить, если узел
c
имеетt
атрибут.has_child($a,'b/c/@t');
Я использую вспомогательную функцию, чтобы проверить, является ли узел допустимым узлом, предоставленным в качестве параметра в функции.
private static function isValidNode($node) { return isset($node) && $node instanceof SimpleXMLElement && !empty($node); }
пример использования:
public function getIdFromNode($node) { if (!self::isValidNode($node)) { return 0; } return (int)$node['id']; }