XML:为什么我的DOM遍历函数仅产生顶级节点



我想我会写一个简单的功能来访问dom树中的所有节点。我写了它,给了它一个不太复杂的XML工作,但是当我运行它时,我只有顶级(domdocument)节点。

请注意,我正在使用PHP的发电机语法:http://php.net/manual/en/language.generators.syntax.php

这是我的功能:

function DOMIterate($node)
{
    yield $node;
    if ($node->hasChildNodes())
    {
        foreach ($node->childNodes as $subnode) {
            // if($subnode != null) {
                DOMIterate($subnode);
            // }
        }
    }
}

和应该打印结果的测试柜代码:

 $doc = new DOMDocument();
    $doc->loadXML($input);
    foreach (DOMIterate($doc) as $node) {
        $type = $node->nodeType;
        if ($type == XML_ELEMENT_NODE) {
            $tag = $node-> tagName;
            echo "$tagn";
        }
        else if ($type == XML_DOCUMENT_NODE) {
            echo "documentn";
        }
        else if ($type == XML_TEXT_NODE) {
            $text = $node->wholeText;
            echo "text: $textn";
        } else {
            $linenum = $node->getLineNo();
            echo "unknown node type: $type at input line $linenumn";
        }
    }

输入XML是前18行https://www.w3schools.com/xml/plant_catalog.xml加上关闭

如果您使用的是PHP7,则可以尝试以下操作:

<?php
$string = <<<EOS
<div level="1">
    <div level="2">
        <p level="3"></p>
        <p level="3"></p>
    </div>
    <div level="2">
        <span level="3"></span>
    </div>
</div>
EOS;
$document = new DOMDocument();
$document->loadXML($string);
function DOMIterate($node)
{
    yield $node;
    if ($node->childNodes) {
        foreach ($node->childNodes as $childNode) {
            yield from DOMIterate($childNode);
        }
    }
}
foreach (DOMIterate($document) as $node) {
    echo $node->nodeName . PHP_EOL;
}

这是一个工作示例-http://sandbox.onlinephpfunctions.com/code/ab4781870f8f9888888207da78b20093b00ea2e8023b请记住,您还将获得标签中包含的文本节点。

在发电机调用的函数中使用 yield不会将值返回到原始生成器的呼叫者。您需要使用yield from来传播值。

function DOMIterate($node)
{
    yield $node;
    if ($node->hasChildNodes())
    {
        foreach ($node->childNodes as $subnode) {
            // if($subnode != null) {
                yield from DOMIterate($subnode);
            // }
        }
    }
}

这需要php 7.如果您使用的是较早版本,请参见php

中的递归生成器

最新更新