309 votes

Comment convertir un tableau en SimpleXML

Comment convertir un tableau en objet SimpleXML en PHP ?

6 votes

Un tableau de quoi ?

1 votes

421voto

Hanmant Points 1757

Voici un code php 5.2 qui convertira un tableau de n'importe quelle profondeur en document xml :

Array
(
    ['total_stud']=> 500
    [0] => Array
        (
            [student] => Array
                (
                    [id] => 1
                    [name] => abc
                    [address] => Array
                        (
                            [city]=>Pune
                            [zip]=>411006
                        )                       
                )
        )
    [1] => Array
        (
            [student] => Array
                (
                    [id] => 2
                    [name] => xyz
                    [address] => Array
                        (
                            [city]=>Mumbai
                            [zip]=>400906
                        )   
                )

        )
)

Le XML généré serait le suivant :

<?xml version="1.0"?>
<student_info>
    <total_stud>500</total_stud>
    <student>
        <id>1</id>
        <name>abc</name>
        <address>
            <city>Pune</city>
            <zip>411006</zip>
        </address>
    </student>
    <student>
        <id>1</id>
        <name>abc</name>
        <address>
            <city>Mumbai</city>
            <zip>400906</zip>
        </address>
    </student>
</student_info>

Extrait de code PHP

<?php
// initializing or creating array
$student_info = array(your array data);

// creating object of SimpleXMLElement
$xml_student_info = new SimpleXMLElement("<?xml version=\"1.0\"?><student_info></student_info>");

// function call to convert array to xml
array_to_xml($student_info,$xml_student_info);

//saving generated xml file
$xml_student_info->asXML('file path and name');

// function defination to convert array to xml
function array_to_xml($student_info, &$xml_student_info) {
    foreach($student_info as $key => $value) {
        if(is_array($value)) {
            if(!is_numeric($key)){
                $subnode = $xml_student_info->addChild("$key");
                array_to_xml($value, $subnode);
            }
            else{
                $subnode = $xml_student_info->addChild("item$key");
                array_to_xml($value, $subnode);
            }
        }
        else {
            $xml_student_info->addChild("$key",htmlspecialchars("$value"));
        }
    }
}

?>

0 votes

Nous avons utilisé ce 'echo $xml_student_info->asXML();' pour afficher ce xml directement mais cela fonctionne pour les grands tableaux de données. lorsque les tableaux de données sont moins de dix éléments, le format xml n'est pas affiché mais seulement un format simple. nous avons utilisé cette fonction header ("Content-type : text/xml") ; pour afficher le format en xml.

0 votes

Si vous voulez avoir plusieurs nœuds avec le même nom (comme je l'ai fait), jetez un œil à la révision 2. Le code force les balises "item##" à être insérées tel qu'il est actuellement.

0 votes

@Mifas J'ai encore modifié votre version modifiée des réponses de Hanmant pour un code plus court. pastebin.com/046N0Cit

227voto

ax. Points 22269

Une courte :

<?php

$test_array = array (
  'bla' => 'blub',
  'foo' => 'bar',
  'another_array' => array (
    'stack' => 'overflow',
  ),
);
$xml = new SimpleXMLElement('<root/>');
array_walk_recursive($test_array, array ($xml, 'addChild'));
print $xml->asXML();

résulte en

<?xml version="1.0"?>
<root>
  <blub>bla</blub>
  <bar>foo</bar>
  <overflow>stack</overflow>
</root>

les clés et les valeurs sont permutées - vous pouvez corriger cela avec array_flip() avant le array_walk. array_walk_recursive nécessite PHP 5. Vous pouvez utiliser array_walk à la place, mais vous n'obtiendrez pas 'stack' => 'overflow' dans le xml alors.

56 votes

Cela ne fonctionnera pas si $test_array a 'more_another_array' comme 'another_array', car la clé 'another_array' n'est pas convertie. Vous aurez donc plusieurs '<overflow>stack</overflow>'.

11 votes

Le site array_flip ne fonctionnera pas, car il ne peut pas retourner les tableaux (comme la fonction another_array à l'intérieur du tableau principal).

15 votes

Où est l'élément xml "another_array" ? Tout est aplati :(

144voto

Lalit Points 581

Les réponses fournies ici ne font que convertir un tableau en XML avec des nœuds, vous ne pouvez pas définir les attributs. J'ai écrit une fonction php qui vous permet de convertir un tableau en php et également de définir des attributs pour des nœuds particuliers dans le xml. L'inconvénient est que vous devez construire un tableau d'une manière particulière avec quelques conventions (seulement si vous voulez utiliser des attributs).

L'exemple suivant vous permettra de définir des attributs en XML également.

Un exemple détaillé et l'utilisation peuvent être trouvés ici : http://www.lalit.org/lab/convert-php-array-to-xml-with-attributes/

<?php    
$books = array(
    '@attributes' => array(
        'type' => 'fiction'
    ),
    'book' => array(
        array(
            '@attributes' => array(
                'author' => 'George Orwell'
            ),
            'title' => '1984'
        ),
        array(
            '@attributes' => array(
                'author' => 'Isaac Asimov'
            ),
            'title' => 'Foundation',
            'price' => '$15.61'
        ),
        array(
            '@attributes' => array(
                'author' => 'Robert A Heinlein'
            ),
            'title' => 'Stranger in a Strange Land',
            'price' => array(
                '@attributes' => array(
                    'discount' => '10%'
                ),
                '@value' => '$18.00'
            )
        )
    )
);
/* creates 
<books type="fiction">
  <book author="George Orwell">
    <title>1984</title>
  </book>
  <book author="Isaac Asimov">
    <title>Foundation</title>
    <price>$15.61</price>
  </book>
  <book author="Robert A Heinlein">
    <title>Stranger in a Strange Land</title>
    <price discount="10%">$18.00</price>
  </book>
</books>
*/
?>

11 votes

Je suis surpris que personne n'ait réagi sur ce point. Cette classe est vraiment utile car elle fait l'inverse de ce que simpleXMLElement va générer. Elle vous donne donc la possibilité d'utiliser SimpleXMLElement dans les deux sens.

4 votes

Je le marquerais comme réponse au lieu de courant. La réponse actuelle ne consiste pas à construire des tableaux récursifs

2 votes

Belle classe. J'ai changé la ligne 128 if(!is_array($arr)) { a if(!is_array($arr) && $arr !== '') { de sorte qu'il n'ajoute pas de nouveau nœud de texte pour les chaînes vides et conserve donc le format abrégé de balise vide, c'est-à-dire 'tag'=>'' es <tag/> au lieu de <tag></tag>

67voto

Francis Lewis Points 3379

J'ai trouvé que toutes les réponses utilisaient trop de code. Voici un moyen simple de le faire :

function to_xml(SimpleXMLElement $object, array $data)
{   
    foreach ($data as $key => $value)
    {   
        if (is_array($value))
        {   
            $new_object = $object->addChild($key);
            to_xml($new_object, $value);
        }   
        else
        {   
            $object->addChild($key, $value);
        }   
    }   
}   

Il suffit ensuite d'envoyer le tableau dans la fonction, qui utilise la récursion, de sorte qu'elle puisse gérer un tableau multidimensionnel :

$xml = new SimpleXMLElement('<rootTag/>');
to_xml($xml, $my_array);

Maintenant, $xml contient un bel objet XML basé sur votre tableau, exactement comme vous l'avez écrit.

print $xml->asXML();

10 votes

C'est la solution que j'aime le plus. Cependant, il serait bien d'ajouter un test sur les touches numériques, par exemple : if ( is_numeric( $key ) ) $key = "numeric_$key"; .

0 votes

@wout Bonne prise. J'ai ajouté. J'ai fait une vérification int cast au lieu de is_numeric parce que is_numeric peut donner certains résultats, bien que techniquement attendus, qui vous déstabiliseraient vraiment.

0 votes

J'utilise cette fonction, mais j'ai modifié $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><rootTag/>'); pour un encodage UTF-8 valide.

39voto

onokazu Points 279
<?php
function array\_to\_xml(array $arr, SimpleXMLElement $xml)
{
    foreach ($arr as $k => $v) {
        is\_array($v)
            ? array\_to\_xml($v, $xml->addChild($k))
            : $xml->addChild($k, $v);
    }
    return $xml;
}

$test\_array = array (
    'bla' => 'blub',
    'foo' => 'bar',
    'another\_array' => array (
        'stack' => 'overflow',
    ),
);

echo array\_to\_xml($test\_array, new SimpleXMLElement('<root/>'))->asXML();

2 votes

Cela échoue si votre tableau contient un tableau interne avec des index numériques. <0>...</0> n'est pas un XML valide.

0 votes

@AdrianoVaroliPiazza ajoutez juste quelque chose comme $k = (is_numeric($k)) ? 'item' : $k; à l'intérieur de la foreach()

0 votes

Si l'une des clés du tableau est nommée "body", cela ne fonctionne pas -- plus précisément, la clé est ignorée et parcourue. J'essaie de comprendre pourquoi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X