将节点添加到 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);
毕竟<Nick>
不是根节点,而是它的第一个孩子
【讨论】:
我还有一个疑问。我如何添加元素;$override=$xml->createElement("Overrideable");$override->setAttribute('enabled','false');$ban->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 树的更深的分支中的主要内容,如果未能解决你的问题,请参考以下文章