Treehouse: Grow your CSS skills. Land your dream job.

Edit XML with PHP

  • # June 16, 2010 at 2:32 am

    I created an admin system for a photography flash portfolio website, in the wordpress admin, in the functions.php file. An XML file is loaded into the flash website but I wanted a way to edit that data. So this system loads the form values in from an xml file.


    The only thing thats not functional is, it doesn’t save the data entered. I can add, remove, and edit the packages on the page, but it won’t save it to the xml file it loads from. If anyone can lend me a hand that would be great!


    # June 16, 2010 at 4:19 pm

    I’m not exactly sure what it is you are looking for, just how to save an xml file, how to create one with php… ect.

    Could you please be more specific?

    Anyways, this is how I learned:

    # June 16, 2010 at 6:14 pm

    Thanks for the reply. I just want to make this form functional. It already loads in data from my XML file. But I want the user to be able to edit it with this form. So since it loads the information in from the xml file, I could just dump all of the XML data and replace it with the new data that are in the fields when it is saved. I would assume this is all done with PHP. This is my xml file currently:

    $750 This is a description for Package 1. $1250 This is a description for Package 2. $1750 This is a description for Package 3. $2000 This is a description for Package 4. $3000 This is a description for Package 5.

    This is the code I wrote for the wordpress admin menu as seen above:

    < ?php function pricing() { ?>

    Edit Pricing

    < ?php
    $doc = new DOMDocument();
    $doc->load( ‘’ );

    $pricing = $doc->getElementsByTagName( “package” );
    foreach( $pricing as $package )
    $titles = $package->getElementsByTagName( “title” );
    $title = $titles->item(0)->nodeValue;

    $prices = $package->getElementsByTagName( “price” );
    $price = $prices->item(0)->nodeValue;

    $descriptions = $package->getElementsByTagName( “description” );
    $description = $descriptions->item(0)->nodeValue;

    echo ”




    < ?php } ?>

    So looking at that image in my last post, PHP would take each box and write a <package> node, for each box, in the xml file when you click save.

    I just need to figure out how to write this with PHP. Does that make more sense?

    # June 17, 2010 at 2:54 pm

    Makes much more sense. I actually did something like this not too long ago. So here’s how I did it…

    I took the current xml file, and looped through it. I had my variables set for the old title, and the newly updated title so I knew which one to replace. I looped through the xml file and copied everything into a new xml, until I got to the outdated block. I then replaced it with the new information I wanted and continued my loop until the end. Once finished, I saved it overwriting the old xml file. And that’s it!

    I modified my large piece of code to give you a smaller one that you should be able to use with little or no modifications. Let me know if you have any questions.

    < ?php
    //Notice how I load the xml location outside the function, incase you have already loaded it.
    $xmlFile = "";//directory/location of your xml file

    function updateXML($oldtitle, $oldprice, $olddesc, $newtitle, $newprice, $newdesc){
    global $xmlFile;//loads the file location set above

    $xml = simplexml_load_file($xmlFile);//loads xml into $xml variable
    $doc = new DOMDocument('1.0');//new xml file that will overwrite the above
    $doc->formatOutput = true;//why not?

    $library = $doc->appendChild($doc->createElement(“pricing”));//creates

    foreach($xml->package as $package) {//loops through the xml file

    $b = $doc->createElement( “package” );//creates

    if ($package->title == $oldtitle && $package->price == $oldprice && $package->description == $olddesc){//if we are at the outdated package, update information
    $name = $doc->createElement( “title” );//creates element <br /> $name->appendChild($doc->createTextNode( $newtitle ));//adds $newtitle value inside the <br /> $b->appendChild( $name );//closes element
    $price = $doc->createElement( “price” );
    $price->appendChild($doc->createTextNode( $newprice ));
    $b->appendChild( $price );
    $desc = $doc->createElement( “description” );
    $desc->appendChild($doc->createTextNode( $newdesc ));
    $b->appendChild( $desc );
    } else {//not at the package we want to update so simply copy over to our new xml
    $name = $doc->createElement( “title” );
    $name->appendChild($doc->createTextNode( $package->title ));
    $b->appendChild( $name );
    $price = $doc->createElement( “price” );
    $price->appendChild($doc->createTextNode( $package->price ));
    $b->appendChild( $price );
    $desc = $doc->createElement( “description” );
    $desc->appendChild($doc->createTextNode( $package->description ));
    $b->appendChild( $desc );

    $library->appendChild( $b );// }

    $doc->save($xmlFile);//save our new xml in place of the old one. overwrites automatically.

    updateXML(‘Package 1′,’$750′,’This is a description for Package 1.’,’a’,’a’,’a’);//will change package 1 to a for everything. example only



    # June 17, 2010 at 3:00 pm

    Thank you so much, but I get the following error:
    Warning: DOMDocument::save( []: failed to open stream: HTTP wrapper does not support writeable connections in /[server-path]/xmledit.php on line 43

    whats wrong here? i set the chmod of pricing.xml to 777

    # June 17, 2010 at 4:48 pm

    First, do you have "" around it if you aren’t using the variable?




    Is the php file you are running on the same server as the xml file? I’m pretty sure they have to be. Also try changing the location to a relative location.

    # June 17, 2010 at 5:38 pm

    both the xml file and xmledit.php are on the root folder (public_html) of my server. I tried both with the var (without quotes) and with the direct location (with quotes) and still, I get the same error. It looks like it would work but maybe I am overlooking something…

    also how do I use this script, do I just open this straight out of my browser, or do I use this as my form action?

    # June 17, 2010 at 5:40 pm


    # June 17, 2010 at 5:43 pm

    ok it works, but how do I use it? It just reset the first group of nodes to "a".

    # June 17, 2010 at 5:52 pm

    Well its a function. You send it the variables that it takes and it will do the work for you.

    Put the function in the page you want to edit the xml file. Then call the function sending it the information it needs.

    updateXML(‘Package 1′,’$750′,’This is a description for Package 1.’,’New Title’,’New Price’,’New Description’);

    The first 3 parameters are the old information of the block of xml you want to change. The last three are the new values you want to change them to. If you used a form, you would need to find a way to store the old information and send both the old and new values to the function. That line above executes the function. So take that out of the example I gave you. Say you sent all the data using a form, you would end up with something like

    updateXML($_Post[‘oldtitle’], $_POST[‘oldprice’], $_POST[‘olddesc’], $_Post[‘newtitle’], $_POST[‘newprice’], $_POST[‘newdesc’]);

    Sorry this is a little hard to explain if you don’t know how to use a function. Make any sense?

    # June 17, 2010 at 6:04 pm

    yes, it does make some sense. I just have to figure out how to pass the veriables. my problem is, this is a dynamic form that you are able to add and remove field groups, as you can see in the image, so i am going to have to figure out how to have them always be:
    title1, pricing1, desc1
    title2, pricing2, desc2
    title3, pricing3, desc3
    title4, pricing4, desc4
    title5, pricing5, desc5


    because lets say the user removes the second box. then it would go:
    title1, pricing1, desc1
    title3, pricing3, desc3
    title4, pricing4, desc4
    title5, pricing5, desc5

    title1, pricing1, desc1
    title2, pricing2, desc2
    title3, pricing3, desc3
    title4, pricing4, desc4
    like it should.

    then when I add a group, it would have to be the number after the last.

    so everytime you add or remove a field group, jquery (or something) will have to rename all of the field attributes to be in order.
    does that sound about right?

    even once I get that in place, how will I tell it the right number of packages to save? (make sense?)

    # June 17, 2010 at 6:19 pm

    if i use a li instead of divs to put my form group in, would jquery be able to associate the number of the li with the attribute of the field? or would I have to use php for this?

    # June 21, 2010 at 10:17 am

    Do you know sql and managing tables/databases? You are attempting to do basically the same thing here without a database. In that case, I would add an id attribute to your packages.

    Also look into using ajax (jQuery can do it easily and well) to save your xml after every necessary change. It sounds like this is a pretty complicated script you are writing here; write out/plan everything you need the script to accomplish and how you would go about doing it. Then knock things out one at a time.

    And you could give each li an attribute and have jquery read/change that value.

    # June 21, 2010 at 11:04 am

    I think I will stick with xml. I don’t know how difficult it would be to load data from a database into flash but I think it would be easier to do that with xml because you wouldn’t need a php file to retrieve the variables from the database.

    So you know what I am trying to accomplish, is there any good resources you know of to learn how to do all this?

    Thanks a lot.

    # June 21, 2010 at 11:20 am

    Actually just found these two links. Not how we have been going about doing this, but it looks promising and can possibly give you an idea to how things work this way. Let me know what ya think.

Viewing 15 posts - 1 through 15 (of 36 total)

You must be logged in to reply to this topic.