php SimpleXML проверить, если ребенок существует


A->b->c могут существовать, но c может и не существовать. Как мне это проверить?

15 51

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);
}

я решил его с помощью

метод xpath возвращает массив совпадающих элементов или false

if(false !== $A->xpath('b/c')) { ...

http://www.php.net/manual/ru/simplexmlelement.xpath.php

после некоторых экспериментов я обнаружил, что единственным надежным методом проверки наличия узла является использование count($xml->someNode).

вот тестовый случай:https://gist.github.com/Thinkscape/6262156

Если у вас есть php 5.3, вы можете просто использовать $a->count(). В противном случае, решение scippie с помощью @count($a->children()) работает хорошо. Я считаю, что мне не нужен @ , но более старые реализации PHP могут понадобиться.

используя if(isset($A->b){ дал мне проблемы, поэтому я попытался if($A->b){ и это сработало!

просто

var_dump(count($xml->node));

вы можете попробовать:

if($A->b->c && $A->b->c != '')

думал, что поделюсь своим опытом. Запуск на 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()

вот скрипт, чтобы показать результаты от каждого:

https://gist.github.com/mchelen/306f4f31f21c02cb0c24

использование 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'];
}