2015-09-16 6 views
0

Я создаю некоторые серверные функции для приложения, которое я создаю.Не удается добавить дочерний элемент дочернего элемента в элемент XML

У меня есть код кода, который вызывает у меня беспокойство.

Предполагается добавить детей в дочерний элемент элемента в документе XML. Вместо этого он заменяет весь файл с новой информацией, и я не могу понять, почему:/

PHP:

function addRole($pid, $id, $name){ 
    echo $pid; 
    $xml = self::getXml(); 

    foreach($xml->children() as $project){ 
     if($project->id == $pid){ 
      echo self::toJSON($project->roles); 
      $roles = $project->roles->children(); 
      echo self::toJSON($roles); 
      $role = $roles->addchild("role"); 
      $role->addChild("id", $id); 
      $role->addChild("name", $name); 
      echo self::toJSON($role); 
      $role->asXml("../data/projects.xml"); 
     } 
    } 
} 

файл XML должен выглядеть следующим образом (это пример фактического XML из projects.xml):

<projects> 
    <project> 
     <id>adultScotland</id> 
     <name>Adults(Scotland)</name> 
     <roles> 
      <role> 
       <id>projectM</id> 
       <name>Project Manager</name> 
      </role> 
     </roles> 
     <courses> 
      <course>Administration of Medication</course> 
      <course>Infection Control</course> 
      <course>Introducing Positive Approaches to Behaviour</course> 
     </courses> 
    </project> 
</projects> 

Может ли кто-нибудь увидеть, что я сделал не так?

Если кто-нибудь хочет, чтобы посмотреть на него, getXML() заключается в следующем:

function getXml(){ 
    $xml=simplexml_load_file("../data/projects.xml") or die("ERROR: Unable to read file"); 
return $xml; 
} 

заранее спасибо за любую помощь :)

+1

Вы перезаписать исходный файл с 'role' узла,' $ ролевые> asXml («../ data/projects.xml»); 'вместо документа. –

+0

... вместо '$ xml-> asXML (...)' – michi

+0

@michi, который должен быть _after_ циклом foreach. (На всякий случай они ожидают, что только c + p, что на месте.) –

ответ

0

У меня есть решение для вашего вопроса. Вы должны изменить свой цикл foreach с моим примером. Я удалил все, что не было необходимым для моего эксперимента.

foreach($xml->children() as $project){ 
    if($project->id == $pid){ 
     $roles = $project->roles; 
     $role = $roles->addchild("role"); 
     $role->addChild("id", $id); 
     $role->addChild("name", $name); 
    } 
} 
$xml->asXML('your_xml_doc_name.xml'); 

Проблема была в вашем коде: $roles = $project->roles->children();. С его помощью вы сами получили роль, но вам нужно получить доступ к дочерним ролям. В simplexml это можно сделать как $roles = $project->roles;. Основная документация по использованию простого симплексного кода http://php.net/manual/ru/simplexml.examples-basic.php

Следующая функция была в asXML-функции. Вам нужно сохранить весь документ, а не только новую роль. Итак, вместо $role->asXml("../data/projects.xml");' in foreach loop, you should print after $ xml-> asXML ('your_xml_doc_name.xml'); `. asXML функция документации http://php.net/manual/ru/simplexmlelement.asxml.php

0

Вы можете получить доступ к <roles> узел без foreach() по xpath() в одной строке кода:

$roles = $xml->xpath("/projects/project[id = 'dummy']/roles")[0]; 

Данное заявление будет ...

  • выбрать все <project>, имеющий ребенок <id> как dummy (надеюсь, это только 1 узел)
  • возвращает его <roles> узел, включая всех детей, как SimpleXML element
  • хранится в массиве $roles
  • по [0] мы ссылаемся на первый элемент только в этом массиве (требуется PHP> = 5,4)

$xml, конечно, объект SimpleXML.

Затем, вы можете добавить новый <role>, как описано выше:

$newrole = $roles->addchild("role"); 
// etc. 

увидеть его в действии: https://eval.in/434484

Смежные вопросы