【问题标题】:Why does count(DOMNode->childNodes) return an incorrect number of children? (PHP and XML) [closed]为什么 count(DOMNode->childNodes) 返回不正确的子节点数? (PHP 和 XML)[关闭]
【发布时间】:2011-06-27 17:05:54
【问题描述】:

我有一个名为 processDeleteForm() 的 PHP 函数,旨在从名为 structure.xml 的 xml 文档中删除指定的节点。到目前为止,我遇到的唯一问题是在 processDeleteForm() 中,它通过循环遍历父节点的每个子节点来搜索要删除的节点,并通过“名称”属性匹配它,但我没有'无法为循环获得正确数量的子节点,因此它在到达正确节点之前停止。相关代码:

function processDeleteForm($dir, $filename)
{
  echo "Processing delete request.<br/>";
  echo "Request to delete ".$filename." from ".$dir.".<br/>";
  $xmlDoc = new DOMDocument();

  $xmlDoc->load("structure.xml");
  $node = dirDOMNodeWritable($dir, $xmlDoc);

  $target;
  echo "Working directory has ".count($node->childNodes)." child(ren).<br/>";
  for($x = 0; $x < count($node->childNodes); $x++)
  {
    if($node->childNodes->item($x)->getAttribute("name") == $filename)
    {
      $target = $node->childNodes->item($x);
      echo "Target found.<br/>";
    }
    else
    {
      echo "Searching for target...<br/>";
    }
  }

  if($target->getAttribute("type") != "directory")
  {
    $fstored = "uploads/".$target->childNodes->item(0)->wholeText;
    unlink($fstored);
  }

  $node->removeChild($target);

  $file = fopen("structure.xml", "w");
  fwrite($file, $xmlDoc->saveXML());

}

结构.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<directory name="root" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="directory">
  <directory name="music" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="directory">
    <directory name="She" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="directory">
      <directory name="Chiptek" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="directory">
        <directory name="mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="directory">
          <file name="intro.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">intro.mp3</file>
          <file name="music.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">music.mp3</file>
          <file name="supersonic.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">supersonic.mp3</file>
          <file name="memories.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">memories.mp3</file>
          <file name="chiptek.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">chiptek.mp3</file>
          <file name="intermission.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">intermission.mp3</file>
          <file name="kicks.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">kicks.mp3</file>
          <file name="1997.mp3" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/mpeg">1997.mp3</file>
        </directory>
        <directory name="ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="directory">
          <file name="intro.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">intro.ogg</file>
          <file name="music.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">music.ogg</file>
          <file name="supersonic.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">supersonic.ogg</file>
          <file name="memories.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">memories.ogg</file>
          <file name="chiptek.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">chiptek.ogg</file>
          <file name="intermission.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">intermission.ogg</file>
          <file name="kicks.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">kicks.ogg</file>
          <file name="1997.ogg" owner="elarsen" read="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" write="aclum,ahoffman,apavlowski,bvollmer,dpotts,drichardson,epiatt,jcantrell,jreeve,kdouglas,kjab,lbrewer,lholliday,mfriedman,norty,pmoore,rlongwell,scatlett,sketcherside,tperkins" type="audio/ogg">1997.ogg</file>
        </directory>
      </directory>
    </directory>
  </directory>
  <directory name="test01" owner="elarsen" read="0" write="0" type="directory"/>
  <directory name="test02" owner="elarsen" read="0" write="0" type="directory"/>
  <directory name="test03" owner="elarsen" read="0" write="0" type="directory"/>
</directory>

*上面应该是xml文件的内容,但我不知道如何显示它。如果有更多关于在 stackoverflow 上格式化 xml 的知识的人可以修复它,我将非常感激。

查看负责创建名为“test01”、“test02”和“test03”的目录的代码可能也很有用:

function processNewForm($dir, $dirName, $readPrivs, $writePrivs)
{
  $readString = "";
  $writeString = "";
  $dirOwner = $_SESSION["user"];

  for($x = 0; $x < count($readPrivs); $x++)
  {
    $readString += $readPrivs[$x].",";
  }
  for($x = 0; $x < count($writePrivs); $x++)
  {
    $writeString += $writePrivs[$x].",";
  }

  $xmlDoc = new DOMDocument();

  $xmlDoc->load("structure.xml");
  $node = dirDOMNodeWritable($dir, $xmlDoc);

  $newDir = $xmlDoc->createElement("directory");
  $newDir->setAttribute("name", $dirName);
  $newDir->setAttribute("owner", $dirOwner);
  $newDir->setAttribute("read", $readString);
  $newDir->setAttribute("write", $writeString);
  $newDir->setAttribute("type", "directory");

  $node->appendChild($newDir);

  $file = fopen("structure.xml", "w");
  fwrite($file, $xmlDoc->saveXML());

}

当前输出如下所示:

Received delete request.
Validating delete request... Request is valid.
Processing delete request.
Request to delete test03/ from /.
Working directory has 1 child(ren).
Searching for target...

Notice: Undefined variable: target in E:\aepi\dev\fileshare.php on line 540

Fatal error: Call to a member function getAttribute() on a non-object in E:\aepi\dev\fileshare.php on line 540

【问题讨论】:

  • 这个dirDOMNodeWritable()函数有什么作用?
  • 它创建了一个 DOMNode,表示从 $xmlDoc 中传递的 XMLDocument 中传递的 $dir 变量中的目录路径,这样当我尝试使用 $node 修改 $xmlDoc 的结构时,它不会崩溃。

标签: php xml dom count


【解决方案1】:

来自PHP manual for count():

返回 var 中的元素个数。如果 var 不是数组或实现了 Countable 接口的对象,则返回 1。

DOMNode::$childNodes 是一个 DOMNodeList 对象。它不是Countable。它总是返回一个(即使是空的)。请改用其length 属性:

$count = $element->childNodes->length;

更新: 从 PHP 7.2 起,DOMNodeList 已变为 Countable。

【讨论】:

  • 我现在真的、真的很蠢。不知何故,当我实际使用长度时,我确信我在代码的其他地方使用了 count() 。谢谢。
  • 有趣的是,我在 Windows 10 设备上的 apache 上安装了 PHP 7.3,并且 count() 实际上在 DOM 上按预期工作。在 High Sierra 上使用 PHP 7.1 回到我的 Mac,它只返回单个第一个节点。
  • @VasilyHall 从参考文档页面上的更改日志中,DOMNodeList 在 7.2 中已变为 Countable。
【解决方案2】:

我猜您的childNodes 包含文本节点以及 XML 标记节点,因为标记之间存在空白。这可能导致childNodes 的计数是您预期的两倍。在尝试获取其属性之前,您应该检查 nodeType 以确保它不是文本节点。

可能在这里:

  for($x = 0; $x < count($node->childNodes); $x++)
  {
    // Verify that you're not working on a text node (type 3 TEXT_NODE)
    if($node->nodeType != 3 && $node->childNodes->item($x)->getAttribute("name") == $filename)
    {
      $target = $node->childNodes->item($x);
      echo "Target found.<br/>";
    }
    else
    {
      echo "Searching for target...<br/>";
    }
  }

【讨论】:

  • 对不起,我应该提到我将空格放在上面的 xml 代码中只是为了便于阅读。 structure.xml 存在于服务器上,没有插入空格。此外,如果是这样的话,它会报告比我想要的更多个孩子,而不是更少,不是吗?
  • 我一定错过了它报告的数量低于预期。对不起。
  • 我想知道为什么我得到的 childNodes 数是实际孩子数的两倍。这篇文章对我有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多