将节点添加到XML树的更深层分支中

时间:2011-07-19 19:01:02

标签: php xml xpath xmlnode

我正在开发一个Web界面,使管理员能够从我的服务器禁止/取消特定用户,该服务器的软件依赖于XML文件来确定用户的禁止状态。最初,'Bans.xml'具有以下内容。

    <Bans version="1.036">
      <Nick>
         <Ban>
           <Overrideable enable="false"/>
           <Nick>cray</Nick>
         </Ban>
      </Nick>
    </Bans>

如何编写php代码以便获取以下XML文件?

    <Bans version="1.036">
      <Nick>
         <Ban>
           <Overrideable enable="false"/>
           <Nick>cray</Nick>
         </Ban>
         <Ban>
           <Overrideable enable="false"/>
           <Nick>newuser</Nick>
         </Ban>
      </Nick>
    </Bans> 

到目前为止,我已设法编写以下脚本:

    <?php
      $xml=new DOMDocument();
      $xml->formatOutput=true;
      $xml->preserveWhiteSpace=false;
      $xml->load("Bans.xml");
      $root=$xml->documentElement;
      $fnode=$root->firstChild;
      $ori=$fnode->childNodes->item(2);
      $nick=$xml->createElement("Nick");
      $nickText=$xml->createTextNode("newuser");
      $nick->appendChild($nickText);
      $ban=$xml->createElement("Ban");
      $ban->appendChild($nick);
      $root->insertBefore($ban,$ori);
      header("Content-type:text/xml");
      $xml->save('Bans.xml');    
     ?>

但上述代码给出的所有内容都是:

    <Bans version="1.036">
      <Nick>
        <Ban>
          <Overrideable enable="false"/>
          <Nick>cray</Nick>
        </Ban>
      </Nick>
      <Ban>
        <Nick>Crayaas</Nick>
      </Ban>
    </Bans>   

--------我设法通过替换来正确添加节点; ---------

    $root->insertBefore($ban,$ori);

使用以下代码;

    $fnode->insertBefore($ban,$ori);

我的最后一个问题是,如何删除特定的禁令,其中nick等于存储在变量$ buser中的用户提供的字符串。我使用了以下代码。但是在条件中使用$ buser会产生错误。

    $buser="newuser";                
    $dom=new DOMDocument();
    $dom->load('settings/Bans.xml');
    $bans=$dom->documentElement;
    $xpath=new DOMXpath($dom);
    $result=$xpath->query('/Bans/Nick/Ban[Nick="$buser"]');
    $result->item(0)->parentNode->removeChild($result->item(0));
    header("Content-type: text/xml");
    $dom->save('settings/Bans.xml');        

如果可以回答这个问题会很高兴;)

2 个答案:

答案 0 :(得分:1)

此:

$root->insertBefore($ban,$ori);

应该是:

$fnode->insertBefore($ban,$ori);

毕竟,<Nick>不是rootnode,而是它的第一个孩子

答案 1 :(得分:1)

你想附加一个像这样的新子树:

 <Ban>
    <Overrideable enable="false"/>
    <Nick>newuser</Nick>
 </Ban>

因此,构建该结构然后appendChild到/ Bans / Nick。

在旁注中,您的元素命名有点值得怀疑,因为您的元素名称具有不同的语义,具体取决于它们出现的位置。虽然你可以做到这一点,但我认为你可以通过完全删除/ Bans / Nick并使用它来减少歧义:

<Bans version="1.036">
   <Ban>
      <Overrideable enable="false"/>
      <Nick>cray</Nick>
   </Ban>
</Bans>

然后你只需附加到根元素。