0

I have an XML file which includes the followings.

<?xml version="1.0"?>
<users><user><firstname>ben</firstname><surname>kim</surname
<email>benkim@test.com</email></user>
<user><firstname>ken</firstname><surname>kim</surname><email>kenkim@test.com</email>   
</user></users>

What I'd like to do is that appending a new user into existing XML above with the codes below. But I doesn't work at all. Could you guys look at them please?

<?php
    header('Content-Type: text/xml');
?>
<?php
    $firstname = $_GET["firstname"];
    $surname = $_GET["surname"];
    $email = $_GET["email"];

    $person = array("firstname"=>$firstname,"surname"=>$surname,"email"=>$email);

    //ECHO (fromXML());

    $xmlDoc = new DOMDocument();
    $xmlDoc->load("test.xml");
    $xmlDoc=$xmlDoc->documentElement;

    toXml($person);

    function toXml($person)
    {
        $users = $xmlDoc->getElementsByTagName('users');

        $user = $xmlDoc->createElement('user');
        $user = $users->appendChild($user);

        $firstname = $xmlDoc->createElement('firstname'); 
        $firstname = $user->appendChild($firstname);   
        $valFirstname = $xmlDoc->createTextNode($person["firstname"]);
        $valFirstname = $firstname->appendChild($valFirstname);

        $surname = $xmlDoc->createElement('surname'); 
        $surname = $user->appendChild($surname);   
        $valSurname = $xmlDoc->createTextNode($person["surname"]);
        $valSurname = $surname->appendChild($valSurname);

        $email = $xmlDoc->createElement('email'); 
        $email = $user->appendChild($email);   
        $valEmail = $xmlDoc->createTextNode($person["email"]);
        $valEmail = $email->appendChild($valEmail);

        $strXml = $xmlDoc->saveXML();
        $handle = fopen("test.xml", "a");
        fwrite($handle, $strXml);
        fclose($handle);
    }
user3503758
  • 77
  • 1
  • 1
  • 9
  • 1
    Your function has a scope issue. `$xmlDoc` variable isn't available inside your function's scope. Pass it as a parameter. Also, [**enable error reporting**](http://stackoverflow.com/a/6575502/1438393) so you can discover similar errors. – Amal Murali Apr 21 '14 at 00:28

2 Answers2

0

Try using SimpleXML instead

$xml = new SimpleXMLElement('your xml here');
$user = $xml->addChild('user');
$user->addChild('firstname', $person["firstname"]);
Machavity
  • 30,841
  • 27
  • 92
  • 100
0

You have multiple issues.

First, $xmlDoc is not available inside your function's scope. For that, you need to either:

  • Pass $xmlDoc as a parameter of your toXml() function (which is recommended)
  • Use the global keyword to tell your function that it needs to fetch $xmlDoc from the global context (which is discouraged)

Then, you don't fetch the root node correctly. In your case, you simply need to fetch it using $xmlDoc->firstChild.

Then, you need to create the different nodes, and then insert them in your root node. Which means that you need to create the elements before appending them to the DOM.

Finally, you are opening the test.xml file in append mode (a). This means that when you'll save your document, you will actually append the content of your xml to the existing content, and thus, your document will be invalid, as it will have a new <?xml ... ?> tag each time you execute the script.

Here is a corrected version of your script. Feel free to ask questions if you have any! :)

<?php

$person = array(
    "firstname" => $_GET["firstname"],
    "surname"   => $_GET["surname"],
    "email"     => $_GET["email"],
);

$xmlDoc = new DOMDocument();

$xmlDoc->preserveWhiteSpace = false;
$xmlDoc->formatOutput = true;
$xmlDoc->load("test.xml");

toXml($person, $xmlDoc);

header('Content-Type', 'application/xml');
exit(file_get_contents('test.xml'));

function toXml(array $person, DOMDocument $xmlDoc)
{
    $users = $xmlDoc->firstChild;
    $user = $xmlDoc->createElement('user');

    $firstname = $xmlDoc->createElement('firstname');
    $textNode = $xmlDoc->createTextNode($person["firstname"]);
    $firstname->appendChild($textNode);
    $user->appendChild($firstname);

    $surname = $xmlDoc->createElement('surname');
    $textNode = $xmlDoc->createTextNode($person["surname"]);
    $surname->appendChild($textNode);
    $user->appendChild($surname);

    $email = $xmlDoc->createElement('email');
    $textNode = $xmlDoc->createTextNode($person["email"]);
    $email->appendChild($textNode);
    $user->appendChild($email);

    $users->appendChild($user);

    $strXml = $xmlDoc->saveXML();
    $handle = fopen("test.xml", "w");
    fwrite($handle, $strXml);
    fclose($handle);
}
Charles Sarrazin
  • 801
  • 7
  • 13
  • thank you it really helped!! do you also know how to find out if the file already exists or not? because i need to make xml file if not existed. – user3503758 Apr 21 '14 at 01:57
  • Just use mode `'w+'`, instead of mode `'w'` :) See [http://www.php.net/manual/en/function.fopen.php](http://www.php.net/manual/en/function.fopen.php) – Charles Sarrazin Apr 21 '14 at 02:01
  • hey Charles Sarrazin, could you explain to me what the following means please? header('Content-Type: text/xml'); exit(file_get_contents('customer.xml')); – user3503758 Apr 21 '14 at 02:12
  • `header('Content-Type', 'application/xml');` makes your content be recognised by the browser as being an XML document. `exit(file_get_contents('test.xml'));` simply exits PHP and displays the content of the file `test.xml` – Charles Sarrazin Apr 21 '14 at 02:17