Создание подэлемента в XML

Я пытаюсь выполнить следующее:

<?xml version="1.0"?>
<books>
<book>
<name>Harry potter</name>
<category>Adventure | Family | Fantasy</category>
<pages>850</pages>
<author>
<author_name>Jhon Doe</author_name>
<author_wiki>http://wikipedia....</author_wiki>
</author>
<description>lorem ipsum blabla</description>
</book>
</books>

Часть, которую я не могу приступить к работе, — это промежуточный элемент автора. Но я не могу идти дальше, я много чего перепробовал, но, похоже, это дает мне только пустые страницы. Что у меня есть сейчас:

<?xml version="1.0"?>
<books>
<book>
<name>Harry potter</name>
<category>Adventure | Family | Fantasy</category>
<pages>850</pages>
<description>lorem ipsum blabla</description>
</book>
</books>

<?php header('Content-Type: text/xml;'); 
// Start XML file, create parent node
$doc = new DOMDocument('1.0');
$root = $doc->createElement('books');
$root = $doc->appendChild($root);
// we want a nice output
$doc->formatOutput = true;
$user = $doc->createElement('book');
$user = $doc->appendChild($user);
$title = $doc->createElement('name');
$title = $user->appendChild($title);
$text = $doc->createTextNode('Harry potter');
$text = $title->appendChild($text);
$title = $doc->createElement('category');
$title = $user->appendChild($title);
$text = $doc->createTextNode('Adventure | Family | Fantasy');
$text = $title->appendChild($text);
$title = $doc->createElement('pages');
$title = $user->appendChild($title);
$text = $doc->createTextNode('850');
$text = $title->appendChild($text);
$title = $doc->createElement('description');
$title = $user->appendChild($title);
$text = $doc->createTextNode('lorem ipsum blabla');
$text = $title->appendChild($text);
$user = $root->appendChild($user);
echo $doc->saveXML();
?>

person user3306814    schedule 13.02.2014    source источник


Ответы (2)


Для добавления узлов в DOM требуется 3 шага

  1. Создайте узел, используя методы документа, такие как createElement() или createTextNode().
  2. Настройте узел и добавьте дочерние узлы
  3. Добавьте узел к его родительскому узлу.

Шаг 2 и 3 взаимозаменяемы. Вы можете настроить узел после его добавления или до этого. appendChild() возвращает узел добавления.

Я сделал отступ вызовов в зависимости от уровня в результирующем xml:

$doc = new DOMDocument('1.0');
$doc->formatOutput = true;

$books = $doc->appendChild($doc->createElement('books'));
  $book = $books->appendChild($doc->createElement('book'));
    $name = $book->appendChild($doc->createElement('name'));
      $name->appendChild($doc->createTextNode('Harry potter'));
    $category = $book->appendChild($doc->createElement('category'));
      $category->appendChild($doc->createTextNode('Adventure | Family | Fantasy'));
    $pages = $book->appendChild($doc->createElement('pages'));
      $pages->appendChild($doc->createTextNode('850'));

    $author = $book->appendChild($doc->createElement('author'));
      $authorName = $author->appendChild($doc->createElement('author_name'));
        $authorName->appendChild($doc->createTextNode('John Doe'));
      $authorWiki = $author->appendChild($doc->createElement('author_wiki'));
        $authorWiki->appendChild($doc->createTextNode('http://wikipedia....'));

    $description = $book->appendChild($doc->createElement('description'));
      $description->appendChild($doc->createTextNode('lorem ipsum blabla'));

echo $doc->saveXML();
person ThW    schedule 13.02.2014
comment
Спасибо за помощь, теперь я все понимаю! - person user3306814; 13.02.2014

Здесь вам нужно добавить сведения об авторе к элементу автора, а не к корневому элементу. Итак, что-то вроде этого будет работать:

header('Content-Type: text/xml;'); 
$doc = new DOMDocument('1.0');
$doc->formatOutput = true;

$book = $doc->createElement("book");
$doc->appendChild($book);

$author = $doc->createElement("author");
$book->appendChild($author); // add author as child of book

// you can add content at the same time as creating the element
$author_name = $doc->createElement("author_name", "John Doe");
// append author name to author element
$author->appendChild($author_name); 

echo $doc->saveXML();

Также обратите внимание, что вы можете сэкономить немного места, создавая текстовые узлы, добавляя текст внутри createElement, хотя этого может быть недостаточно в некоторых обстоятельствах, поскольку значение не экранировано (ссылка: php.net - я просто использовал его здесь для быстроты).

Пример вывода:

<book>
  <author>
    <author_name>John Doe</author_name>
  </author>
</book>
person stckrboy    schedule 13.02.2014
comment
Спасибо за помощь, но теперь, как поместить элемент author внутри элемента book? - person user3306814; 13.02.2014
comment
Это делается во многом таким же образом. Я обновил свой пример кода. Вы просто меняете элемент, к которому добавляете дочерний элемент. - person stckrboy; 13.02.2014
comment
Спасибо, это мне очень помогло! - person Roger; 22.07.2016