Проверка php SimpleXML, если ребенок существует - PullRequest
56 голосов
/ 13 октября 2009

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

Ответы [ 15 ]

118 голосов
/ 13 октября 2009

Может быть лучше обернуть это в isset()

if(isset($A->b->c)) { // c exists

Таким образом, если $A или $A->b не существует ... оно не взорвется.

39 голосов
/ 17 марта 2011

SimpleXML всегда возвращает объект. Если дочерний элемент отсутствует, возвращается пустой объект.

if( !empty($a->b)){
  var_dump($a->b);
}
8 голосов
/ 24 ноября 2010

Я решил это с помощью функции children() и выполнил count(), игнорируя ошибку PHP, если дочерних элементов нет, поставив @ перед счетчиком вызовов. Это глупо, но работает:

$identification = $xml->identification;
if (@count($identification->children()) == 0)
  $identification = $xml->Identification;

Я ненавижу это ...

7 голосов
/ 10 апреля 2014

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

Вот тестовый пример: https://gist.github.com/Thinkscape/6262156

5 голосов
/ 25 сентября 2013

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

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

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

4 голосов
/ 24 марта 2011

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

2 голосов
/ 18 апреля 2017

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

Вы также можете проверить атрибуты. Чтобы проверить, имеет ли узел c атрибут t.

has_child($a,'b/c/@t');
2 голосов
/ 15 марта 2017

Просто

var_dump(count($xml->node));
2 голосов
/ 06 июня 2012

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

1 голос
/ 07 июня 2018

Я использую вспомогательную функцию, чтобы проверить, является ли узел допустимым узлом, предоставленным в качестве параметра в функции.

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'];
}
...