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

Posted

技术标签:

【中文标题】将节点添加到 XML 树的更深的分支中【英文标题】:Add nodes into deeper branches of XML tree 【发布时间】:2011-07-19 19:01:01 【问题描述】:

我正在开发一个 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');        

如果这个问题也能回答我会很高兴;)

【问题讨论】:

【参考方案1】:

这个:

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

应该是:

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

毕竟&lt;Nick&gt;不是根节点,而是它的第一个孩子

【讨论】:

我还有一个疑问。我如何添加元素; 顺便说一句,非常感谢队友。您的回答确实帮助解决了我的问题。 $override=$xml-&gt;createElement("Overrideable");$override-&gt;setAttribute('enabled','false');$ban-&gt;appendChild($override);【参考方案2】:

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

 <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>

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

【讨论】:

您好,感谢您的回复。是的,我没有注意到元素命名的变化。我不想编辑我的 XML 树,因为使用此 XML 文件的应用程序依赖于特定的树布局来执行其功能;) @Cray 很好,即使您保留布局,IMO 仍然更容易附加新的子节点而不是使用 insertBefore。

以上是关于将节点添加到 XML 树的更深的分支中的主要内容,如果未能解决你的问题,请参考以下文章

保存前将节点添加到XML

将命名空间添加到 xml 根节点 c#

如何将XML子节点添加到父节点c#

详解SimpleXML添加_修改_删除_遍历XML节点属性

使用 Jackson 将 XML 属性添加到手动构建的节点树

如何将工具提示添加到 Telerik 树视图