2010-08-05 90 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