当前位置: 首页 > 知识库问答 >
问题:

DOM无法将节点追加到DOMNodeList(PHP 7.3)中的元素

伍光济
2023-03-14

我正在使用PHP7.3编写一个函数,该函数循环访问输入中接收的一组节点,并将它们添加到文档中。

public function appendChildren($nodes)
{
    foreach ($nodes as $node){

        $this->appendChild($node);
    }
}

它可以工作,但当输入值不是数组而是DOMNodeList时,它只在第一个元素上循环。

要再现问题,请执行以下操作:

<?php

$doc = new DOMDocument();
$doc->formatOutput=true;

$root =  $doc->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'md:root');
$nodes[] = $doc->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'KeyInfo');
$nodes[] = $doc->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'KeyFile');
$nodes[] = $doc->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'KeyStory');
$nodes[] = $doc->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'KeyRole');

foreach($nodes as $node)
{
    $root->appendChild($node);
}
$nlist = $root->childNodes;
$newroot = $doc->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'md:newroot');


foreach($nlist as $node)
{
   $newroot->appendChild($node);
}

echo 'size of root: '.$root->childNodes->count()."\n";
echo 'size of newroot: '.$newroot->childNodes->count()."\n";

$doc->appendChild($newroot);
echo $doc->saveXML();

预期产出:

size of root: 4
size of newroot: 4
<?xml version="1.0"?>
<md:newroot xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
  <md:KeyInfo/>
  <md:KeyFile/>
  <md:KeyStory/>
  <md:KeyRole/>
</md:root>

然而我得到:

size of root: 3
size of newroot: 1
<?xml version="1.0"?>
<md:newroot xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
  <md:KeyInfo/>
</md:newroot>

循环是不完整的,并且不知为什么第一个元素的引用被从前一个列表中移除并添加到后一个列表中(因此大小为3)。而且,如果我评论

 $newroot->appendChild($node);

循环按预期遍历列表。函数appendChild()如何可能停止循环?而为什么会发生在第一次迭代之后呢?

有人能说明一下这种行为吗?

共有1个答案

易扬
2023-03-14

由于AppendChild,迭代时$NList正在更改。您正在移动内容。您可以通过调试看到这一点

for($i = 0; $i < $nlist->length; $i++)
{
    $newroot->appendChild($nlist->item($i));
}

所以你需要这样重写

while($nlist->length)
{
    $newroot->appendChild($nlist->item(0));
}
 类似资料:
  • 问题内容: 如果类型不匹配,可以将一些元素追加到elasticsearch字段吗?如果我有这样的文件: 而且我想像这样附加另一个标签字段“蓝色”: 我想要的结果类似于: 我知道这个: 用于将字符串追加到另一个字符串 还有这个: 用于将另一个元素追加到列表。那么有什么办法可以将另一个元素附加到字符串字段呢?谢谢您的任何建议。 问题答案: 您可以做的是添加针对字段类型的测试,然后将其转换为数组。该脚本

  • 本文向大家介绍javascript将DOM节点添加到文档的方法实例分析,包括了javascript将DOM节点添加到文档的方法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了javascript将DOM节点添加到文档的方法。分享给大家供大家参考。具体如下: 这里对两种方法进行了比较:第一种:先创建所有节点,再添加到文档方式的运行时长;第二种:先向文档添加一个空容器,然后每创建一个节

  • 在本章中,我们将讨论已存在元素的节点。在这节中将学习添加(或插入)新节点 - 在现有子节点之前或之后追加新的子节点 在文本节点中插入数据 添加属性节点 以下方法可用于将节点元素添加/附加到DOM中 - 1. 使用appendChild()方法 方法用于向现有子节点之后添加新的子节点。 语法 方法的语法如下 - 其中, − 要添加的新节点。 此方法返回已添加的节点()。 示例 以下示例(append

  • 问题内容: 这是我需要帮助的功能: 原版的: 通缉: 问题答案: 以下完整示例将从当前目录中读取 现有 文件,追加新服务器,然后将文件重写为。没有现有的.xml文件,该功能将无法正常运行,因此您需要修改代码以处理这种情况。 示例 server.xml 文件: 对代码的主要更改是 未 创建新的“ root”元素。上面的示例仅使用现有节点中的当前根节点,然后追加一个新的 Server 元素并重新写入该

  • 我有两个服务器在Docker群,但当我需要添加第三个服务器-我得到的结果: 来自守护进程的错误响应:rpc错误:code=14 desc=grpc:连接不可用 一个网络中的所有服务器。 有什么问题吗?

  • 问题内容: 我有一个简单的字典,其定义如下: 现在,我想在此字典中添加一个元素: 如何添加到现有词典中? 问题答案: 您正在使用。除非出于某种原因明确需要将其设为该类型,否则我建议使用Swift字典。 您可以通过迅捷的字典任何期望的功能而无需任何额外的工作,因为和无缝地弥合彼此。Swift的本机方式的优点是字典使用泛型类型,因此,如果将其定义为键和值,就不会错误地使用不同类型的键和值。(编译器代表