PHP中的SimpleXMLIterator不以BFS方式遍历XML树

PHP中的SimpleXMLIterator不以BFS方式遍历XML树,php,xml,tree,iterator,Php,Xml,Tree,Iterator,我试图在php版本5.6.11中使用SimpleXMLIterator以BFS顺序迭代XML树。但是,我发现它只遍历嵌套在第1级、第0级根节点正下方的XML元素,跳过第2级、第3级……的所有嵌套元素 那么,如何让迭代器以BFS方式遍历XML树呢 其中提到迭代器应该是递归的。代码如下: <?php function getXMLCode() { $xmlCode = <<<XML <home> <livingroom>

我试图在php版本5.6.11中使用
SimpleXMLIterator
以BFS顺序迭代XML树。但是,我发现它只遍历嵌套在第1级、第0级根节点正下方的XML元素,跳过第2级、第3级……的所有嵌套元素

那么,如何让迭代器以BFS方式遍历XML树呢

其中提到迭代器应该是递归的。代码如下:

<?php

function getXMLCode() {

  $xmlCode = <<<XML
  <home>
    <livingroom>
      <sofa>
        <leftPillow></leftPillow>
        <rightPillow></rightPillow>
      </sofa>
      <television></television>
    </livingroom>
    <bedroom>
      <bed>
        <sheet></sheet>
        <duvet></duvet>
        <pillow></pillow>
      </bed>
    </bedroom>
    <bathroom>
      <sink></sink>
      <toilet></toilet>
      <bath>
        <bathtap></bathtap>
      </bath>
    </bathroom>
    <kitchen>
      <fridge>
        <lettuce>
          <snail></snail>
        </lettuce>
      </fridge>
    </kitchen>
  </home>
XML;

  return $xmlCode;

}

function test() {

  $xmlCode = getXMLCode();

  $simpleXMLIterator = new SimpleXMLIterator($xmlCode);

  foreach ($simpleXMLIterator as $xmlElement) {

    echo $xmlElement->getName(), "\n";

  }

}

test();
预期产出:

home
livingroom
bedroom
bathroom
kitchen
sofa
television
bed
sink
toilet
bath
fridge
leftPillow
rightPillow
sheet
duvet
pillow
bathtap
lettuce
snail
使用以下命令:

$it = new RecursiveIteratorIterator(
    new SimpleXmlIterator($xml),
    RecursiveIteratorIterator::SELF_FIRST
);

foreach ($it as $key => $value){
    print(trim($key) . PHP_EOL);
}

使用SimpleXMLIterator遍历XML树BFS样式,这是问题最初提出的问题。不幸的是,由于SimpleXMLElement的设计方式,似乎无法使用SimpleXMLIterator输出根元素

<?php

function getXMLCode() {

  $xmlCode = <<<XML
  <home>
    <livingroom>
      <sofa>
        <leftPillow></leftPillow>
        <rightPillow></rightPillow>
      </sofa>
      <television></television>
    </livingroom>
    <bedroom>
      <bed>
        <sheet></sheet>
        <duvet></duvet>
        <pillow></pillow>
      </bed>
    </bedroom>
    <bathroom>
      <sink></sink>
      <toilet></toilet>
      <bath>
        <bathtap></bathtap>
      </bath>
    </bathroom>
    <kitchen>
      <fridge>
        <lettuce>
          <snail></snail>
        </lettuce>
      </fridge>
    </kitchen>
  </home>
XML;

  return $xmlCode;

}

function test() {

  $xmlCode = getXMLCode();

  $currentSimpleXMLIterator = new SimpleXMLIterator($xmlCode);

  $nonTraversedSimpleXMLIterators = array($currentSimpleXMLIterator);

  while (count($nonTraversedSimpleXMLIterators) > 0) {

    $currentSimpleXMLIterator = array_shift($nonTraversedSimpleXMLIterators);

    for ($currentSimpleXMLIterator->rewind(); $currentSimpleXMLIterator->valid(); $currentSimpleXMLIterator->next()) {

      if ($currentSimpleXMLIterator->hasChildren()) {

        $childSimpleXMLIterator = $currentSimpleXMLIterator->getChildren();

        array_push($nonTraversedSimpleXMLIterators, $childSimpleXMLIterator);

      }

      echo $currentSimpleXMLIterator->current()->getName(), "\n";

    }

  }

}

test();

您的答案仅涵盖第2级列出的要素,但不包括第3级要素,例如。请更新您的答案以包含任意的XML元素嵌套,好吗?我已经尝试了您更新的代码,但它对我无效。这些代码中始终忽略了顶层,因此您将永远无法获得
主页
。如果你需要的话,把它再深一层。通常你知道什么是最高级别。再试一次,我想我现在明白了。我忘了先添加
递归迭代器::SELF_
选项。我也更新了ideone。谢谢你的回答,非常感谢。唯一的问题是,您的遍历是DFS遍历(深度优先),而我正在寻找BFS遍历(bredth优先),并在单独的答案中发布了它。
<?php

function getXMLCode() {

  $xmlCode = <<<XML
  <home>
    <livingroom>
      <sofa>
        <leftPillow></leftPillow>
        <rightPillow></rightPillow>
      </sofa>
      <television></television>
    </livingroom>
    <bedroom>
      <bed>
        <sheet></sheet>
        <duvet></duvet>
        <pillow></pillow>
      </bed>
    </bedroom>
    <bathroom>
      <sink></sink>
      <toilet></toilet>
      <bath>
        <bathtap></bathtap>
      </bath>
    </bathroom>
    <kitchen>
      <fridge>
        <lettuce>
          <snail></snail>
        </lettuce>
      </fridge>
    </kitchen>
  </home>
XML;

  return $xmlCode;

}

function test() {

  $xmlCode = getXMLCode();

  $currentSimpleXMLIterator = new SimpleXMLIterator($xmlCode);

  $nonTraversedSimpleXMLIterators = array($currentSimpleXMLIterator);

  while (count($nonTraversedSimpleXMLIterators) > 0) {

    $currentSimpleXMLIterator = array_shift($nonTraversedSimpleXMLIterators);

    for ($currentSimpleXMLIterator->rewind(); $currentSimpleXMLIterator->valid(); $currentSimpleXMLIterator->next()) {

      if ($currentSimpleXMLIterator->hasChildren()) {

        $childSimpleXMLIterator = $currentSimpleXMLIterator->getChildren();

        array_push($nonTraversedSimpleXMLIterators, $childSimpleXMLIterator);

      }

      echo $currentSimpleXMLIterator->current()->getName(), "\n";

    }

  }

}

test();
livingroom
bedroom
bathroom
kitchen
sofa
television
bed
sink
toilet
bath
fridge
leftPillow
rightPillow
sheet
duvet
pillow
bathtap
lettuce
snail