web-dev-qa-db-fra.com

php SimpleXML vérifier si un enfant existe

A->b->c peut exister mais c peut ne pas exister. Comment puis-je le vérifier?

58
An employee

Il pourrait être préférable de l'envelopper dans une isset()

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

De cette façon, si $A ou $A->b n'existe pas ... ça n'explose pas.

121
null

SimpleXML renvoie toujours Object. S'il n'y a pas d'enfant, un objet vide est retourné.

if( !empty($a->b)){
  var_dump($a->b);
}
39
CedCannes

Je l'ai résolu en utilisant la fonction children() et en faisant une count() dessus, en ignorant une erreur PHP s'il n'y a pas d'enfants en mettant un @ avant le décompte. C'est stupide, mais ça marche:

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

Je déteste ça...

8
scippie

Après quelques expérimentations, j'ai découvert que la seule méthode fiable pour vérifier si un nœud existe est d'utiliser count($xml->someNode).

Voici un cas de test: https://Gist.github.com/Thinkscape/6262156

7
Artur Bodera

La méthode xpath renvoie un tableau d'éléments correspondants ou false

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

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

5
user1391077

Si vous avez PHP 5.3, vous pouvez simplement utiliser $a->count(). Sinon, la solution de scippie utilisant @count($a->children()) fonctionne bien. Je trouve que je n'ai pas besoin du @ mais plus ancien PHP peuvent en avoir besoin.

4
Alex Matulich

L'utilisation de if(isset($A->b){ m'a posé des problèmes, j'ai donc essayé if($A->b){ et cela a fonctionné!

2
Daydah

Simplement

var_dump(count($xml->node));
2
Oğuz Can Sertel

Utilisation de xpath:

function has_child(\SimpleXMLElement $parent=null, string $xpathToChild)
{
    return isset($parent) && !empty($parent->xpath('('.$xpathToChild.')[1]'));
}

$parent est un parent indirect ou direct du nœud enfant à vérifier et $xpathToChild est un xpath de l'enfant par rapport à $parent.

()[1] Est parce que nous ne voulons pas sélectionner tous les nœuds enfants. Un seul suffit.

Pour vérifier si $ a-> b-> c existe:

has_child($a,'b/c');

Vous pouvez également vérifier les attributs. Pour vérifier si le nœud c possède l'attribut t.

has_child($a,'b/c/@t');
2
CITBL

Les 3 façons dont je peux confirmer le travail dans PHP 5.5.23 utilisaient isset()count() ou empty()

Voici un script pour montrer les résultats de chacun:

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

1
Mike Chelen

J'utilise une fonction d'assistance pour vérifier si un nœud est un nœud valide fourni comme paramètre dans la fonction.

private static function isValidNode($node) {
  return isset($node) && $node instanceof SimpleXMLElement && !empty($node);
}

Exemple d'utilisation:

public function getIdFromNode($node) {
  if (!self::isValidNode($node)) {
    return 0;
  }
  return (int)$node['id'];
}
1
ph.dev

Tu pourrais essayer:

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

J'ai pensé partager mon expérience. En cours d'exécution sur 5.4, j'ai essayé de tester avec 'isset' et 'empty', mais aucun n'a fonctionné pour moi. J'ai fini par utiliser is_null.

if(!is_null($xml->scheduler->outterList->innerList)) {
    //do something
}
0
user857276

Espaces de noms

Sachez que si vous utilisez des espaces de noms dans votre fichier XML, vous devrez inclure ceux-ci dans vos appels de fonction lors de la recherche d'enfants, sinon il renverra ZERO à chaque fois:

if ($XMLelement->children($nameSpace,TRUE)->count()){
    //do something here 
}
0
g-man