W3docs

haschildren()

Aprende cómo PHP's SimpleXMLIterator::hasChildren() indica si el elemento XML actual del iterador tiene nodos hijo, con ejemplos ejecutables y errores comunes.

Qué hace hasChildren()

hasChildren() es un método de la clase SimpleXMLIterator. Devuelve true cuando el elemento en el que el iterador está posicionado actualmente tiene al menos un elemento hijo, y false cuando ese elemento es un nodo hoja (solo texto o vacío).

Proviene de la interfaz RecursiveIterator de PHP, que implementan tanto SimpleXMLIterator como SimpleXMLElement. Su función es indicarle a un motor de recorrido recursivo: "¿debo descender a este nodo?" Esa es la idea clave y la fuente de la mayor parte de la confusión:

Advertencia

hasChildren() no pregunta "¿tiene hijos $this?" Pregunta "¿tiene hijos el elemento en la posición actual del iterador?" Normalmente se llama mientras se itera con rewind() / valid() / next(), o se deja que un RecursiveIteratorIterator lo llame internamente, no directamente sobre un elemento arbitrario.

public SimpleXMLIterator::hasChildren(): bool

El método no recibe parámetros y devuelve un bool. Para leer los hijos una vez que devuelve true, combínalo con getChildren().

Configurar un SimpleXMLIterator

hasChildren() solo existe en SimpleXMLIterator, así que crea uno a partir de tu cadena XML con new SimpleXMLIterator(), o carga un documento y conviértelo. Aquí hay un pequeño catálogo donde un elemento tiene hijos y otro no:

<?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";
    }
}

Salida:

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

Observa que el bucle recorre el iterador manualmente con rewind(), valid(), next(), key() y current(). hasChildren() informa sobre el elemento en el que se encuentra el cursor en ese momento.

Recorrer todo el árbol de forma recursiva

El verdadero beneficio de hasChildren() aparece cuando pasas el iterador a un RecursiveIteratorIterator. Ese contenedor llama a hasChildren() y getChildren() por ti, descendiendo automáticamente para que puedas aplanar un documento anidado de cualquier profundidad:

<?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";
}

Salida:

shelf
  book
    title
  desk

Aquí nunca llamas a hasChildren() manualmente — RecursiveIteratorIterator lo usa internamente para decidir cuándo recursar.

Cuándo usarlo

  • Estás iterando una estructura XML desconocida y necesitas saber si debes profundizar antes de leer los valores.
  • Estás construyendo una vista de árbol, migas de pan o una lista plana a partir de XML anidado.
  • Quieres que la maquinaria de iteradores de PHP (RecursiveIteratorIterator, filtros) recorra el XML por ti en lugar de escribir bucles foreach anidados.

Si simplemente quieres los hijos de un elemento conocido, generalmente no necesitas hasChildren() en absoluto — llama a children() sobre un SimpleXMLElement y comprueba si el resultado está vacío con count().

Errores comunes

  • Llamarlo en SimpleXMLElement. Un SimpleXMLElement simple creado con simplexml_load_file() o simplexml_load_string() implementa RecursiveIterator, pero la semántica de hasChildren() pertenece a SimpleXMLIterator. Usa esa clase cuando necesites este método.
  • Esperar que detecte atributos o texto. hasChildren() solo examina los elementos hijo. Un elemento que contiene solo texto o solo atributos devuelve false.
  • Llamarlo antes de posicionar el cursor. Siempre haz rewind() (o itera) primero; el resultado refleja la posición actual, que no está definida antes del primer elemento.

Conclusión

SimpleXMLIterator::hasChildren() es el guardián del recorrido recursivo de XML: indica si el elemento actual del iterador tiene elementos hijo para que tu código —o un RecursiveIteratorIterator— sepa cuándo descender. Combínalo con getChildren() para leer esos hijos, y recurre a children() o a la guía completa de SimpleXML cuando solo necesites los contenidos de un nodo directamente.

Práctica

Práctica
¿Qué devuelve SimpleXMLIterator::hasChildren()?
¿Qué devuelve SimpleXMLIterator::hasChildren()?
Was this page helpful?