A->b->c
peut exister mais c
peut ne pas exister. Comment puis-je le vérifier?
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.
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);
}
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...
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
La méthode xpath renvoie un tableau d'éléments correspondants ou false
if(false !== $A->xpath('b/c')) { ...
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.
L'utilisation de if(isset($A->b){
m'a posé des problèmes, j'ai donc essayé if($A->b){
et cela a fonctionné!
Simplement
var_dump(count($xml->node));
Utilisation de xpath:
function has_child(\SimpleXMLElement $parent=null, string $xpathToChild)
{
return isset($parent) && !empty($parent->xpath('('.$xpathToChild.')[1]'));
}
où $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');
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:
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'];
}
Tu pourrais essayer:
if($A->b->c && $A->b->c != '')
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
}
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
}