W3docs

haschildren()

Aprenda como o SimpleXMLIterator::hasChildren() do PHP indica se o elemento XML atual do iterador possui nós filhos, com exemplos executáveis e armadilhas comuns.

O que hasChildren() faz

hasChildren() é um método da classe SimpleXMLIterator. Ele retorna true quando o elemento em que o iterador está posicionado atualmente possui pelo menos um elemento filho, e false quando esse elemento é um nó folha (somente texto ou vazio).

Ele vem da interface RecursiveIterator do PHP, que tanto SimpleXMLIterator quanto SimpleXMLElement implementam. Sua função é informar ao mecanismo de travessia recursiva: "devo descer neste nó?" Essa é a ideia central e a fonte da maior parte da confusão:

Aviso

hasChildren() não pergunta "o $this tem filhos?" Ele pergunta "o elemento na posição atual do iterador tem filhos?" Normalmente você o chama durante um loop com rewind() / valid() / next(), ou deixa um RecursiveIteratorIterator chamá-lo por você — não diretamente em um elemento arbitrário.

public SimpleXMLIterator::hasChildren(): bool

O método não recebe parâmetros e retorna um bool. Para ler os filhos quando ele retornar true, combine-o com getChildren().

Configurando um SimpleXMLIterator

hasChildren() existe apenas em SimpleXMLIterator, portanto crie um a partir de sua string XML com new SimpleXMLIterator(), ou carregue um documento e faça o cast. Aqui está um pequeno catálogo onde um elemento tem filhos e outro não:

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

Saída:

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

Observe que o loop percorre o iterador manualmente com rewind(), valid(), next(), key() e current(). hasChildren() informa sobre o elemento em que o cursor está posicionado naquele momento.

Percorrendo a árvore inteira recursivamente

O verdadeiro benefício de hasChildren() aparece quando você passa o iterador para um RecursiveIteratorIterator. Esse wrapper chama hasChildren() e getChildren() por você, descendo automaticamente para que você possa achatar um documento aninhado de qualquer profundidade:

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

Saída:

shelf
  book
    title
  desk

Você nunca chama hasChildren() manualmente aqui — o RecursiveIteratorIterator o usa internamente para decidir quando fazer a recursão.

Quando utilizá-lo

  • Você está iterando uma estrutura XML desconhecida e precisa saber se deve aprofundar antes de ler os valores.
  • Você está construindo uma visualização em árvore, breadcrumb ou lista achatada a partir de XML aninhado.
  • Você quer que o mecanismo de iteradores do PHP (RecursiveIteratorIterator, filtros) percorra o XML por você em vez de escrever loops foreach aninhados.

Se você simplesmente quer os filhos de um elemento conhecido, geralmente não precisa de hasChildren() — chame children() em um SimpleXMLElement e verifique se o resultado está vazio com count().

Armadilhas comuns

  • Chamá-lo em SimpleXMLElement. Um SimpleXMLElement simples criado com simplexml_load_file() ou simplexml_load_string() implementa RecursiveIterator, mas a semântica amigável de hasChildren() pertence ao SimpleXMLIterator. Use essa classe quando quiser este método.
  • Esperar que detecte atributos ou texto. hasChildren() olha apenas para elementos filhos. Um elemento que contém apenas texto ou apenas atributos retorna false.
  • Chamá-lo antes de posicionar o cursor. Sempre faça rewind() (ou itere) primeiro; o resultado reflete a posição atual, que é indefinida antes do primeiro elemento.

Conclusão

SimpleXMLIterator::hasChildren() é o guardião da travessia recursiva de XML: ele informa se o elemento atual do iterador possui elementos filhos para que seu código — ou um RecursiveIteratorIterator — saiba quando descer. Combine-o com getChildren() para ler esses filhos, e recorra a children() ou ao guia completo de SimpleXML quando precisar apenas do conteúdo de um nó diretamente.

Prática

Prática
O que SimpleXMLIterator::hasChildren() retorna?
O que SimpleXMLIterator::hasChildren() retorna?
Was this page helpful?