php SimpleXML проверяет, существует ли дочерний элемент
A->b->c
может существовать, но c
может и не существовать. Как мне это проверить?
15 answers
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);
}
Я решил эту проблему, используя функцию children()
и выполнив над ней count()
, игнорируя ошибку PHP, если детей нет, поставив @ перед вызовом счетчика. Это глупо, но это работает:
$identification = $xml->identification;
if (@count($identification->children()) == 0)
$identification = $xml->Identification;
Я ненавижу это...
Метод xpath возвращает массив совпадающих элементов или false
if(false !== $A->xpath('b/c')) { ...
После некоторых экспериментов я обнаружил, что единственным надежным методом проверки наличия узла является использование count($xml->someNode)
.
Вот тестовый пример: https://gist.github.com/Thinkscape/6262156
Если у вас PHP 5.3, вы можете просто использовать $a->count()
. В противном случае решение Скиппи с использованием @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" и "пустой", но ни то, ни другое не сработало для меня. В итоге я использовал 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'];
}