2010-08-05 52 views
0

我有一个XML文档,并希望使用SimpleXML在特定位置插入新节点。使用SimpleXML添加子节点

原始XML是这样的:

<epp 
    xmlns="urn:ietf:params:xml:ns:epp-1.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd" 
> 
    <command> 
    <create> 
     <domain:create 
     xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" 
     xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd" 
     > 
     <domain:period unit="y"></domain:period> 
     </domain:create> 
    </create> 
    </command> 
</epp> 

<domain:create>我需要添加以下节点后:

<domain:ns> 
    <domain:hostAttr> 
    <domain:hostName></domain:hostName> 
    <domain:hostAddr ip="v4"></domain:hostAddr> 
    </domain:hostAttr> 
</domain:ns> 

我怎么能这样做?我曾经尝试这样做:

$xmlObj = simplexml_load_file('myXMLFile.xml'); 
$nsNode = $xmlObj->command->create->children(self::OBJ_URI_DOMAIN)->create->addChild('domain:ns'); 
$hostAttr = $nsNode->addChild('domain:hostAttr'); 
$hostName = $hostAttr->addChild('domain:hostName'); 
$hostAddr = $hostAttr->addChild('domain:hostAddr'); 
$hostAddr->addAtribute('ip', 'v4'); 

在此第一线,我得到这样的警告:

Warning: SimpleXMLElement::addChild() [simplexmlelement.addchild]: Cannot add child. Parent is not a permanent member of the XML tree

在第二行,也正因为如此,我越来越:

Fatal error: Call to a member function addChild() on a non-object

在此先感谢。其他说明: - php版本高于5.1; - 我以后在这个相同的XML上成功添加了子节点。

+0

看起来像http://www.sitepoint.com/forums/showthread.php?p=4665410 – Tomalak 2010-08-05 09:34:27

+0

的副本这是我绝望的程度。 :(对不起,我认为他们是无关的。:s你可以删除,如果你认为它更合适。 – MEM 2010-08-05 09:39:55

+0

没关系,我刚刚在谷歌搜索过程中发现该错误消息的帖子,让我们看看需要多长时间一个解决方案。:) – Tomalak 2010-08-05 09:44:37

回答

1

我无法重现的第一个错误

<?php 
echo phpversion(), "\n"; 
// $xmlObj = simplexml_load_file('myXMLFile.xml'); 
$xmlObj = getDoc(); 

$nsNode = $xmlObj->command->create->children('urn:ietf:params:xml:ns:domain-1.0')->create->addChild('domain:ns'); 
$nsNode->addChild('foo', 'Mary had a little lamb...'); 
echo $xmlObj->asxml(); 

function getDoc() { 
    return new SimpleXMLElement('<epp 
    xmlns="urn:ietf:params:xml:ns:epp-1.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd" 
    > 
    <command> 
     <create> 
     <domain:create 
      xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" 
      xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd" 
     > 
      <domain:period unit="y"></domain:period> 
     </domain:create> 
     </create> 
    </command> 
    </epp>'); 
} 

打印

5.3.2 
<?xml version="1.0"?> 
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"> 
    <command> 
     <create> 
     <domain:create xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"> 
      <domain:period unit="y"/> 
     <domain:ns><domain:foo>Mary had a little lamb...</domain:foo></domain:ns></domain:create> 
     </create> 
    </command> 
    </epp> 
+0

非常感谢您的时间VolkerK。好的...唯一的区别是,我正在抓取一个XML文件。我需要保持这一点,以维持整体结构。我会一步一步地翻拍所有内容,并在今天晚些时候提供一些反馈 - 我希望没有人能够通过我现在通过的内容。 :s – MEM 2010-08-05 11:56:04

+0

不知道你是否还在我身边,我发现: 好的...我已经找到了开关,但我还没有看到其他东西...仍然: 这个作品: $ nsNode = $ xmlObj->命令 - > create->孩子( '瓮:IETF:PARAMS:XML:NS:域-1.0') - > create->的addChild( '域:纳秒'); 这不,并引发我的警告: $ nsNode = $ xmlObj-> command-> create-> children(self :: OBJ_URI_DOMAIN) - > create-> addChild('domain:ns'); 我有这件事上我的课: 常量OBJ_URI_DOMAIN = '金塔:IETF:PARAMS:XML:NS:EPP:域1.0' 可能会导致这样的行为是什么? – MEM 2010-08-05 13:51:58

+0

这些URI是不同的。 :完成。 :) 非常感谢。 – MEM 2010-08-05 13:57:09

1

您希望孩子添加到<create>

$nsNode = $xmlObj->command->create->addChild('domain:ns'); 

children()方法返回一个筛选的子节点列表。这个列表 - 正如错误信息所示 - 不是文档树的永久成员,它不能被添加到。

添加子只有相应父元素上工作,或者操作就不叫“的addChild”,而是“addSibling” - 这是DOM的概念不是如何工作的。

PS:您的第二个错误消息(“调用非对象上的成员函数”)是普通sloppiness的结果。你不能只使用对象,不检查,它实际上是,你的代码缺乏这方面的检查:

if ($nsNode !== null) { 
    $hostAttr = $nsNode->addChild('domain:hostAttr'); 
    $hostName = $hostAttr->addChild('domain:hostName'); 
    $hostAddr = $hostAttr->addChild('domain:hostAddr'); 
    $hostAddr->addAttribute('ip', 'v4'); 
} else { 
    echo "Oops, addChild() failed!"; 
} 
+0

我明白了。所以这里的错误是因为我假设'是''的孩子,但事实并非如此? 要添加的节点需要是''和''的兄弟在''内,''在''内,但是我正在读它吗? 我现在更好地理解为什么这个错误,这是一个很大的帮助,但我仍然想念为什么addChild('domain:ns')会这样做。我有$ xmlObj-> command-> extension-> children(self :: EXT_URI_DOMAIN) - > create-> addChild('ptdomain:autoRenew');它的工作原理 :s – MEM 2010-08-05 09:54:00

+0

您不能添加到'children()',句点的返回值。如果您需要添加到此方法返回的节点之一,请保存该方法的返回值,从中选择一个特定节点,然后调用'addChild()'。 – Tomalak 2010-08-05 10:01:14

+0

对不起,我的坏。我改变了这个帖子,$ nsNode = $ xmlObj-> command-> create-> children(self :: OBJ_URI_DOMAIN) - > create-> addChild('domain:ns');这是我的意图。 所以在这里,我们不是直接访问列表,而是该列表的一个节点。这就是我的其他命令工作的原因。 如果您的上次回复仍然适用此评论后,请让我知道。 :) – MEM 2010-08-05 10:06:36