我以为我会编写一个简单的函数来访问DOM树中的所有节点。我写了它,给它一个不太复杂的XML工作,但是当我运行它时,我只得到了顶级(DOMDocument)节点。
请注意,我使用的是PHP的Generator语法: http://php.net/manual/en/language.generators.syntax.php
这是我的功能:
$doc = new DOMDocument();
$doc->loadXML($input);
foreach (DOMIterate($doc) as $node) {
$type = $node->nodeType;
if ($type == XML_ELEMENT_NODE) {
$tag = $node-> tagName;
echo "$tag\n";
}
else if ($type == XML_DOCUMENT_NODE) {
echo "document\n";
}
else if ($type == XML_TEXT_NODE) {
$text = $node->wholeText;
echo "text: $text\n";
} else {
$linenum = $node->getLineNo();
echo "unknown node type: $type at input line $linenum\n";
}
}
应该打印结果的测试用例代码:
((LinearLayout) findViewById(R.id.chartView)).removeAllViewsInLayout();
输入XML是前18行 https://www.w3schools.com/xml/plant_catalog.xml 加上结束
答案 0 :(得分:0)
如果您使用的是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/ab4781870f8f988207da78b20093b00ea2e8023b 请记住,您还将获得标记中包含的文本节点。
答案 1 :(得分:0)
在从生成器调用的函数中使用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.如果您使用的是早期版本,请参阅Recursive generators in PHP