Question

I want to build an XML document in PHP.

I chose DOMDocument, and i know i have to use methods like createElement, createTextNode, appendChild, etc. to build my XML.

This is how i generated the xml with just one node containing vehicle information:

<?php
$doc = new DOMDocument ( '1.0', 'utf-8' );
$vehicles = $doc->createElement ( "Vehicles" );

$vehicle = $doc->createElement("Vehicle");
$vehicle_num = $doc->createElement("Number");
$vehicle_desc = $doc->createElement("Description");
$vehicle_year = $doc->createElement("Year");
$vehicle_make = $doc->createElement("Make");
$vehicle_model = $doc->createElement("Model");
$vehicle_color = $doc->createElement("Color");

$vehicle_num->appendChild($doc->createTextNode("AW2CM31Y8"));
$vehicle_year->appendChild($doc->createTextNode("2013"));
$vehicle_make->appendChild($doc->createTextNode("VOLKSWAGEN"));
$vehicle_model->appendChild($doc->createTextNode("NEW BEETLE"));
$vehicle_color->appendChild($doc->createTextNode("Black"));

$vehicle_desc->appendChild($vehicle_year);
$vehicle_desc->appendChild($vehicle_make);
$vehicle_desc->appendChild($vehicle_model);
$vehicle_desc->appendChild($vehicle_color);

$vehicle->appendChild($vehicle_num);
$vehicle->appendChild($vehicle_desc);

$vehicles->appendChild($vehicle);
$doc->appendChild ( $vehicles );

header ( "Content-type: text/xml" );
echo $doc->saveXML ();

But, what if i want to build an xml with say 100 nodes containing not only vehicle information, but also other nodes above and below it. This process would be too laborious.

So, is there an easy way of creating nodes and adding values to them in xml with php? I am concerned with the number of lines of code that i am supposed to write.

Was it helpful?

Solution

The first thing that comes to mind is that you have got code-repetition. You perhaps want to reduce that. This can be done by moving duplicate code into a function of it's own.

To do that fast, PHP has closures. Let's line that up:

You have a collection of vehicles and each vehicle just has properties and values. So you add a property to a vehicle. BTW, createElement does take a text already as value, so that you don't need to create the text-nodes. So let's wrap the duplicate code into functions and then just call these functions to create the XML. That already - through parametrization - shows your structure. Just differ between the definitions of the functions (first part) and the apply of those (second part):

<?php
/**
 * Create XML Document with PHP in an easy way
 *
 * @link http://stackoverflow.com/q/19702911/367456
 */

/**
 * @param DOMNode $node
 * @return DOMDocument
 */
$doc = function (DOMNode $node = NULL) {
    return $node ? ($node->ownerDocument ? : $node) : new DOMDocument();
};

/**
 * @param DOMElement $element
 * @param string $property
 * @param string $text
 * @return DOMElement the element the proeprty was added to
 */
$prop = function (DOMElement $element, $property, $text) {
    return $element->appendChild(
        $element->ownerDocument->createElement($property, $text)
    );
};

/**
 * @param DOMNode $element
 * @param string $name
 * @return DOMElement
 */
$element = function (DOMNode $element, $name) use ($doc) {
    return $element->appendChild(
        $doc($element)->createElement($name)
    );
};

So after all those functions have been defined, on to the second part:

$prop(
    $vehicle = $element(
        $vehicles = $element(
            $doc()
            , 'Vehicles'
        )
        , 'Vehicle'
    )
    , "Number"
    , "AW2CM31Y8"
);

$prop(
    $vehicle
    , "Year"
    , "2013"
);

$prop(
    $vehicle
    , "Make"
    , "VOLKSWAGEN"
);

$prop(
    $vehicle
    , "Model"
    , "NEW BEETLE"
);

$prop(
    $vehicle
    , "Color"
    , "Black"
);

Et voila. This has revealed some structure. Code-duplication has been removed as well. The only thing left is to finally echo the result out:

header("Content-type: text/xml");
echo $doc($vehicles)->saveXML();

If you look at the code you can even read that it literally does reverse the data-structure to create the XML. So next thing would be to make use of some kind of traversal, but that needs the definition of a data-structure first, not only the definition of the code-structure as it has been done so far (and which should already be of use for you).

Online Example: https://eval.in/59090

OTHER TIPS

It seems to me what you're really looking for is XML Serialisation of an object with some sort of control over the document created therein.

To this end you might want to look at the XMLSerializer project - https://bitbucket.org/schmijos/xmlserializer

Which will taken an array/PHP Object and serialize it into XML.

I recommend you to create xml with the same structure, and use it as template. So you need only fill this xml.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top