2

I have an array like so:

[0] => Array
        (
            [Project] => Array
                (
                    [ExternalProjectID] => 53
                    [ProjectName] => Doon Creek
                    [Location] => Array
                        (
                            [Address] => 123 Fake Street
                            [City] => Toronto
                            [Province] => ON
                            [Latitude] => 43.0000
                            [Longitude] =>  -80.0000
                        )

                    [Website] => http://www.website.com/our-communities.php?newcommunity=53
                    [ContactInformation] => Array
                        (
                            [ContactPhone] => 555-5555
                            [ContactEmail] => [email protected]
                            [SalesOfficeAddress] => 123 Fake Street
                            [SalesOfficeCity] => Toronto
                            [SalesOfficeProvince] => ON
                        )

                )

        )

Now I am trying to covert this to XML exactly how this looks in the array, like Project should be a node with everything inside, Location should also be a node with everything inside the Location array inside that node, along with ContactInformation.

This is what I have:

$xml = new SimpleXMLElement();

$node = $xml->addChild('Projects');

array_to_xml($newArray, $node);

echo $xml->asXML();
die();

function array_to_xml($array, &$xml) {
    foreach($array as $key => $value) {
        if(is_array($value)) {
            if(!is_numeric($key)){
                $subnode = $xml->addChild("$key");
                array_to_xml($value, $xml);
            } else {
                array_to_xml($value, $xml);
            }
        } else {
            $xml->addChild("$key","$value");
        }
    }
}

but Project, Location and ContactInformation return as like so:

<Projects>
      <Project />
      <ExternalProjectID>53</ExternalProjectID>
      <ProjectName>Doon Creek</ProjectName>
      <Location />
      <Address>123 Fake St.</Address>
      <City>Toronto</City>
      <Province>ON</Province>
      <Latitude>43.0000</Latitude>
      <Longitude>-80.000</Longitude>
      <Website>http://www.website.com/our-communities.php?newcommunity=53</Website>
      <ContactInformation />
      <ContactPhone>555-5555</ContactPhone>
      <ContactEmail>[email protected]</ContactEmail>
      <SalesOfficeAddress>123 Fake Street</SalesOfficeAddress>
      <SalesOfficeCity>Toronto</SalesOfficeCity>
      <SalesOfficeProvince>ON</SalesOfficeProvince>
      <Project />
</Projects>

My question is how do I fix my XML Output?

2
  • 2
    Have you referred this? Commented Jun 3, 2016 at 15:30
  • 1
    The second answer worked for me. Commented Jun 3, 2016 at 15:51

3 Answers 3

6

Almost had it! You simply had to pass the $subnode, not $xml into the recursive call of function:

// XML BUILD RECURSIVE FUNCTION
function array_to_xml($array, &$xml) {        
    foreach($array as $key => $value) {               
        if(is_array($value)) {            
            if(!is_numeric($key)){
                $subnode = $xml->addChild($key);
                array_to_xml($value, $subnode);
            } else {
                array_to_xml($value, $subnode);
            }
        } else {
            $xml->addChild($key, $value);
        }
    }        
}

// EXAMPLE ARRAY
$newArray = array(
                 "Project" =>
                  array("ExternalProjectID" => 53,
                        "ProjectName" => "Doon Creek",
                        "Location" => 
                         array ("Address" => "123 Fake Street",
                                "City" => "Toronto",
                                "Province" => "ON",
                                "Latitude" => 43.0000,
                                "Longitude" => -80.0000),
                        "Website" => 
                        "http://www.website.com/our-communities.php?newcommunity=53",
                        "ContactInformation" => 
                         array("ContactPhone" => "555-5555",
                               "ContactEmail" => "[email protected]",
                               "SalesOfficeAddress" => "123 Fake Street",
                               "SalesOfficeCity" => "Toronto",
                               "SalesOfficeProvince" => "ON")
                       )
                );

// CREATING XML OBJECT
$xml = new SimpleXMLElement('<Projects/>'); 
array_to_xml($newArray, $xml);

// TO PRETTY PRINT OUTPUT
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
$domxml->loadXML($xml->asXML());

echo $domxml->saveXML();

Output

<?xml version="1.0"?>
<Projects>
  <Project>
    <ExternalProjectID>53</ExternalProjectID>
    <ProjectName>Doon Creek</ProjectName>
    <Location>
      <Address>123 Fake Street</Address>
      <City>Toronto</City>
      <Province>ON</Province>
      <Latitude>43</Latitude>
      <Longitude>-80</Longitude>
    </Location>
    <Website>http://www.website.com/our-communities.php?newcommunity=53</Website>
    <ContactInformation>
      <ContactPhone>555-5555</ContactPhone>
      <ContactEmail>[email protected]</ContactEmail>
      <SalesOfficeAddress>123 Fake Street</SalesOfficeAddress>
      <SalesOfficeCity>Toronto</SalesOfficeCity>
      <SalesOfficeProvince>ON</SalesOfficeProvince>
    </ContactInformation>
  </Project>
</Projects>
Sign up to request clarification or add additional context in comments.

2 Comments

It throws the undefined variable in else condition $subnode. Can you check which variable should be there on non numeric $key?
@JigneshBhavani, if you are trying to implement this solution on a different XML than OP's sample, please ask a new question.
2

In general, it is verified the key is numeric, but the correct one is if the first one is numeric, if there is something empty "_" is added

<?php
$file = 'https://raw.githubusercontent.com/ZiTAL/flickr-php-cli/master/composer.json';
$file = file_get_contents($file);
$array = json_decode($file, true);

$dom = new DOMDocument('1.0', 'utf-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$root = $dom->createElement('root');
$dom->appendChild($root);

array2xml($array, $root, $dom);

echo $dom->saveXML();

function array2xml($array, $node, &$dom)
{
    foreach($array as $key => $value)
    {
        if(preg_match("/^[0-9]/", $key))
            $key = "node-{$key}";
        $key = preg_replace("/[^a-z0-9_\-]+/i", '', $key);

        if($key==='')
            $key = '_';

        $a = $dom->createElement($key);
        $node->appendChild($a);

        if(!is_array($value))
            $a->appendChild($dom->createTextNode($value));
        else
            array2xml($value, $a, $dom);
    }
}

input:

{
    "name": "thefox/flickr-cli",
    "description": "Upload and download Flickr photos, photo sets, directories via shell.",
    "license": "GPL-3.0",
    "type": "project",
    "keywords": [
        "Flickr",
        "Upload",
        "Download",
        "Photo",
        "CLI"
    ],
    "homepage": "https://github.com/TheFox/flickr-cli",
    "authors": [
        {
            "name": "Christian Mayer",
            "email": "[email protected]",
            "homepage": "https://fox21.at"
        }
    ],
    "require": {
        "php": "^7.0",
        "rezzza/flickr": "^1.1",
        "symfony/yaml": "^2.3",
        "symfony/console": "^3.1",
        "symfony/filesystem": "^3.1",
        "symfony/finder": "^3.1",
        "monolog/monolog": "^1.21",
        "guzzlehttp/guzzle": "^3.8",
        "lusitanian/oauth": "^0.2",
        "rych/bytesize": "^1.0",
        "doctrine/dbal": "^2.5"
    },
    "require-dev": {
        "phpstan/phpstan": "^0.7",
        "squizlabs/php_codesniffer": "^3.0"
    },
    "autoload": {
        "psr-4": {
            "": "src"
        }
    },
    "bin": [
        "bin/flickr-cli"
    ]
}

output:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <name>thefox/flickr-cli</name>
  <description>Upload and download Flickr photos, photo sets, directories via shell.</description>
  <license>GPL-3.0</license>
  <type>project</type>
  <keywords>
    <node-0>Flickr</node-0>
    <node-1>Upload</node-1>
    <node-2>Download</node-2>
    <node-3>Photo</node-3>
    <node-4>CLI</node-4>
  </keywords>
  <homepage>https://github.com/TheFox/flickr-cli</homepage>
  <authors>
    <node-0>
      <name>Christian Mayer</name>
      <email>[email protected]</email>
      <homepage>https://fox21.at</homepage>
    </node-0>
  </authors>
  <require>
    <php>^7.0</php>
    <rezzzaflickr>^1.1</rezzzaflickr>
    <symfonyyaml>^2.3</symfonyyaml>
    <symfonyconsole>^3.1</symfonyconsole>
    <symfonyfilesystem>^3.1</symfonyfilesystem>
    <symfonyfinder>^3.1</symfonyfinder>
    <monologmonolog>^1.21</monologmonolog>
    <guzzlehttpguzzle>^3.8</guzzlehttpguzzle>
    <lusitanianoauth>^0.2</lusitanianoauth>
    <rychbytesize>^1.0</rychbytesize>
    <doctrinedbal>^2.5</doctrinedbal>
  </require>
  <require-dev>
    <phpstanphpstan>^0.7</phpstanphpstan>
    <squizlabsphp_codesniffer>^3.0</squizlabsphp_codesniffer>
  </require-dev>
  <autoload>
    <psr-4>
      <_>src</_>
    </psr-4>
  </autoload>
  <bin>
    <node-0>bin/flickr-cli</node-0>
  </bin>
</root>

Comments

0

REFER

    <?php
    // function defination to convert array to xml
    function array_to_xml( $data, &$xml_data ) {
        foreach( $data as $key => $value ) {
            if( is_array($value) ) {
                if( is_numeric($key) ){
                    $key = 'item'.$key; //dealing with <0/>..<n/> issues
                }
                $subnode = $xml_data->addChild($key);
                array_to_xml($value, $subnode);
            } else {
                $xml_data->addChild("$key",htmlspecialchars("$value"));
            }
         }
    }

    // initializing or creating array
    $data = array('total_stud' => 500);

    // creating object of SimpleXMLElement
    $xml_data = new SimpleXMLElement('<?xml version="1.0"?><data></data>');

    // function call to convert array to xml
    array_to_xml($data,$xml_data);

    //saving generated xml file; 
    $result = $xml_data->asXML('/file/path/name.xml');

    ?>

Documentation on SimpleXMLElement::asXML used in this snippet

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.