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

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

Однако я столкнулся с одной проблемой, которую не мог решить самостоятельно. В связанном решении один и тот же объект обновляется снова и снова без добавления в него какой-либо новой информации:

Пример, «третий тестовый пост»:

<postslist>
    <post>
        <name>Third Post</name>
        <date>2013-11-05</date>
        <time>00:00</time>
        <text>There is some more post text here.</text>
    </post>
</postslist>

И «четвертый тестовый пост»:

<postslist>
    <post>
        <name>Fourth Post</name>
        <date>2013-11-05</date>
        <time>00:00</time>
        <text>There is even more post text here.</text>
    </post>
</postslist>

Мой PHP до сих пор похож на это:

        $postname = $_POST["name"];
        $postdate = $_POST["date"];
        $posttime = $_POST["time"];
        $posttext = $_POST["posttext"];

        $postname = htmlentities($postname, ENT_COMPAT, 'UTF-8', false);
        $postdate = htmlentities($postdate, ENT_COMPAT, 'UTF-8', false);
        $posttime = htmlentities($posttime, ENT_COMPAT, 'UTF-8', false);
        $posttext = htmlentities($posttext, ENT_COMPAT, 'UTF-8', false);

        $xml = simplexml_load_file("posts.xml");

        $xml->post = "";
        $xml->post->addChild('name', $postname);
        $xml->post->addChild('date', $postdate);
        $xml->post->addChild('time', $posttime);
        $xml->post->addChild('text', $posttext);

        $doc = new DOMDocument('1.0');
        $doc->formatOutput = true;
        $doc->preserveWhiteSpace = true;
        $doc->loadXML($xml->asXML(), LIBXML_NOBLANKS);
        $doc->save('posts.xml');

Что я надеюсь сделать, так это создать несколько элементов «post» и добавить дочерние элементы только к самому новому элементу.

Любая помощь/советы будут оценены.


person DesignedMoodily    schedule 01.11.2013    source источник
comment
Вам нужно отредактировать файл, а не создавать его заново всегда.   -  person hakre    schedule 02.11.2013


Ответы (2)


Во-первых, вы не должны смешивать функции simplexml_ и DOMDocument. Первый является оберткой для второго (и, на мой взгляд, не особенно удачной). На вашем месте я бы просто использовал DOMDocument.

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

$doc->load('posts.xml', LIBXML_NOBLANKS); // load the posts file with DOMDocument

$newPost = $doc->createElement('post'); // create a new <post> element
$newPost->appendChild($doc->createElement('name', $postname));
$newPost->appendChild($doc->createElement('date', $postdate));
$newPost->appendChild($doc->createElement('time', $posttime));
$newPost->appendChild($doc->createElement('text', $posttext));

$document->documentElement->appendChild($newPost); // add the new <post> to the document

$doc->save('posts.xml');
person lonesomeday    schedule 01.11.2013
comment
Спасибо за подсказку и решение. Это сработало как шарм! - person DesignedMoodily; 01.11.2013

Вам нужно сначала открыть файл, чтобы вы могли его редактировать, иначе вы все время заменяете весь документ, а не добавляете к нему.

Вот краткий пример того, как это работает с SimpleXML, который до сих пор достаточно прост, чтобы выполнять эту работу:

$file = 'posts.xml';

$xml  = simplexml_load_file($file); // load existing file
$post = $xml->addChild('post'); // add new post child

// assign values to the post object:
$post->name = $_POST["name"];
$post->date = $_POST["date"];
$post->time = $_POST["time"];
$post->text = $_POST["posttext"];

$xml->saveXML($file); //save file with changes

... и полностью совместим с родственной библиотекой DOMDocument на случай, если вам понадобится какая-то функциональность оттуда. Они совместно используют одни и те же объекты памяти.

person hakre    schedule 02.11.2013