W3docs

haschildren()

Apprenez comment PHP SimpleXMLIterator::hasChildren() indique si l'élément XML courant de l'itérateur possède des nœuds enfants, avec des exemples.

Ce que fait hasChildren()

hasChildren() est une méthode de la classe SimpleXMLIterator. Elle retourne true lorsque l'élément sur lequel l'itérateur est actuellement positionné possède au moins un élément enfant, et false lorsque cet élément est un nœud feuille (texte uniquement ou vide).

Elle provient de l'interface RecursiveIterator de PHP, que SimpleXMLIterator et SimpleXMLElement implémentent toutes deux. Son rôle est d'indiquer à un moteur de traversée récursive : « dois-je descendre dans ce nœud ? » C'est l'idée clé, et la source de la plupart des confusions :

Avertissement

hasChildren() ne demande pas « est-ce que $this a des enfants ? » Elle demande « est-ce que l'élément à la position courante de l'itérateur a des enfants ? » Vous l'appelez normalement en bouclant avec rewind() / valid() / next(), ou vous laissez un RecursiveIteratorIterator l'appeler pour vous — pas directement sur un élément arbitraire.

public SimpleXMLIterator::hasChildren(): bool

La méthode ne prend aucun paramètre et retourne un bool. Pour lire les enfants une fois qu'elle retourne true, associez-la à getChildren().

Configurer un SimpleXMLIterator

hasChildren() n'existe que sur SimpleXMLIterator, donc créez-en un à partir de votre chaîne XML avec new SimpleXMLIterator(), ou chargez un document et effectuez un transtypage. Voici un petit catalogue où un élément a des enfants et l'autre non :

<?php

$xml = new SimpleXMLIterator(<<<XML
<store>
  <book>
    <title>Modern PHP</title>
    <author>Josh Lockhart</author>
  </book>
  <note>Closed on holidays</note>
</store>
XML);

for ($xml->rewind(); $xml->valid(); $xml->next()) {
    if ($xml->hasChildren()) {
        echo $xml->key() . " has children:\n";
        foreach ($xml->getChildren() as $name => $value) {
            echo "  {$name}: {$value}\n";
        }
    } else {
        echo $xml->key() . " (leaf): " . $xml->current() . "\n";
    }
}

Sortie :

book has children:
  title: Modern PHP
  author: Josh Lockhart
note (leaf): Closed on holidays

Remarquez que la boucle parcourt l'itérateur manuellement avec rewind(), valid(), next(), key() et current(). hasChildren() rend compte de l'élément sur lequel se trouve le curseur à ce moment-là.

Parcourir tout l'arbre de manière récursive

Le véritable intérêt de hasChildren() apparaît lorsque vous passez l'itérateur à un RecursiveIteratorIterator. Ce wrapper appelle hasChildren() et getChildren() pour vous, descendant automatiquement pour que vous puissiez aplatir un document imbriqué de n'importe quelle profondeur :

<?php

$xml = new SimpleXMLIterator(<<<XML
<library>
  <shelf>
    <book>
      <title>PHP Basics</title>
    </book>
  </shelf>
  <desk>Front entrance</desk>
</library>
XML);

$tree = new RecursiveIteratorIterator(
    $xml,
    RecursiveIteratorIterator::SELF_FIRST
);

foreach ($tree as $name => $node) {
    echo str_repeat('  ', $tree->getDepth()) . $name . "\n";
}

Sortie :

shelf
  book
    title
  desk

Vous n'appelez jamais hasChildren() manuellement ici — RecursiveIteratorIterator l'utilise en interne pour décider quand effectuer la récursion.

Quand l'utiliser

  • Vous itérez sur une structure XML inconnue et devez savoir s'il faut descendre plus profondément avant de lire les valeurs.
  • Vous construisez une arborescence, un fil d'Ariane ou une liste aplatie à partir de XML imbriqué.
  • Vous souhaitez que la machinerie d'itérateur de PHP (RecursiveIteratorIterator, filtres) traverse le XML pour vous plutôt que d'écrire des boucles foreach imbriquées.

Si vous voulez simplement les enfants d'un élément connu, vous n'avez généralement pas besoin de hasChildren() du tout — appelez children() sur un SimpleXMLElement et vérifiez si le résultat est vide avec count().

Pièges courants

  • L'appeler sur SimpleXMLElement. Un SimpleXMLElement simple créé avec simplexml_load_file() ou simplexml_load_string() implémente RecursiveIterator, mais la sémantique conviviale de hasChildren() appartient à SimpleXMLIterator. Utilisez cette classe lorsque vous souhaitez cette méthode.
  • S'attendre à ce qu'elle détecte les attributs ou le texte. hasChildren() examine uniquement les éléments enfants. Un élément contenant uniquement du texte ou uniquement des attributs retourne false.
  • L'appeler avant de positionner le curseur. Effectuez toujours un rewind() (ou itérez) en premier ; le résultat reflète la position courante, qui est indéfinie avant le premier élément.

Conclusion

SimpleXMLIterator::hasChildren() est le gardien de la traversée XML récursive : elle indique si l'élément courant de l'itérateur a des éléments enfants, afin que votre code — ou un RecursiveIteratorIterator — sache quand descendre. Associez-la à getChildren() pour lire ces enfants, et utilisez children() ou le guide SimpleXML plus complet lorsque vous avez juste besoin du contenu d'un nœud directement.

Pratique

Pratique
Que retourne SimpleXMLIterator::hasChildren() ?
Que retourne SimpleXMLIterator::hasChildren() ?
Was this page helpful?