Добавление дочерних узлов с использованием SimpleXML - PullRequest
0 голосов
/ 05 августа 2010

У меня есть документ XML, и я хочу вставить новый узел в определенное место, используя 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');

В этой первой строке я получаю это предупреждение:

Предупреждение: SimpleXMLElement :: addChild () [simplexmlelement.addchild]: невозможно добавить ребенка. Родитель не является постоянным член дерева XML

На второй строке и из-за этого я получаю:

Неустранимая ошибка: вызов функции-члена addChild () для необъекта

Заранее спасибо.

Дополнительные примечания: - версия php выше 5.1; - Я успешно добавил дочерние узлы в тот же XML.

Ответы [ 2 ]

1 голос
/ 05 августа 2010

Я не могу воспроизвести первую ошибку

<?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>
1 голос
/ 05 августа 2010

Вы хотите, чтобы дочерний элемент был добавлен в <create>.

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

Метод children() возвращает отфильтрованный список дочерних узлов.Этот список - как указывает сообщение об ошибке - не является постоянным членом дерева документов, к нему нельзя добавить.

Добавление дочернего элемента работает только с соответствующим родительским элементом илиоперация будет называться не «addChild», а «addSibling» - и это не то, как работает концепция DOM.

PS: Ваше второе сообщение об ошибке («Вызов функции-члена наобъект ") является результатом регулярного разгильдяйства.Вы не можете просто использовать объект, не проверив, что он действительно там , в вашем коде отсутствует эта проверка:

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!";
}
...