IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Transformer le tableau [array] en XML document par DOMDocument [PHP 5.4]


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut Transformer le tableau [array] en XML document par DOMDocument
    Bonjour,
    Je suis vraiment perdu depuis quelques jours.
    J'ai un fichier en format json et je veux donner ses informations dans un fichier XML.
    J'arrive calculer le prix total et mettre dans un fichier XML (jusqu'ai ici c'est simple).

    voici mon json :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    {
       "ville": "VERDUN",
       "articles": [
          {
             "prix": "2.00",
             "quantite": "1",
             "nom_item": "tomates",
             "tax": [
                {
                   "prix": "0.25",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.50",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          },
          {
             "prix": "1.00",
             "quantite": "1",
             "nom_item": "patates",
             "tax": [
                {
                   "prix": "0.12",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.75",
                   "quantite": "1",
                   "nom_item": "taxe3"
                }
             ]
          }
       ]
    }
    et voici mon fichier XML que je veux obtenir
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
       	<chaque_item>
    		<prix>2.00</prix>
    		<quantite>1</quantite>
    		<nom_item>tomates</nom_item>
    	</chaque_item>
    	<chaque_item>
    		<prix>1.00</prix>
    		<quantite>1</quantite>
    		<nom_item>patates</nom_item>
    	</chaque_item>
        <chaque_item>
    		<prix>0.37</prix>
    		<quantite>1</quantite>
    		<nom_item>taxe1</nom_item>
    	</chaque_item>
        <chaque_item>
    		<prix>0.50</prix>
    		<quantite>1</quantite>
    		<nom_item>taxe2</nom_item>
    	</chaque_item> 
    	<chaque_item>
    		<prix>0.25</prix>
    		<quantite>1</quantite>
    		<nom_item>taxe2</nom_item>
    	</chaque_item> 
      </articles>
    </resume>

    Je fais les premiers 5 lignes de mon fichier XML avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    header('Content-Type: text/xml');
    header('Content-Type: application/xml');
     
    $doc= new DOMDocument('1.0', 'UTF-8');
     
     
    //formatage
    $doc->preserveWhiteSpace = false;
    $doc->formatOutput = true;
     
    //creating an xslt adding processing line
    /*$xslt = $doc->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="Vigieresume.xslt"');
    //adding it to the xml
    $doc->appendChild($xslt);*/
     
     
    		$datajs = "fruit.json"; // 3article (1 fruit + 2 taxe)
    		$datajs = file_get_contents($datajs);
     
    		$data = json_decode($datajs);
     
     
    		$city= $data->ville;
    		$total_items_avec_taxe = '0.0000';
     
     
    // create resume element
    $lavel1_resume = $doc->createElement("resume");
    $doc->appendChild($lavel1_resume);
     
     
     
     
    		// create child element -------------------|
    	$ville = $doc->createElement("ville");
    	$lavel1_resume->appendChild($ville);
     
    			// create text node =====================================||
    	$text_ville = $doc->createTextNode($city);
    	$ville->appendChild($text_ville);	
     
     
    //Calcule de prix total avec taxe
     
    		 //$data = json_decode($datajs);
    		 $data_decode_array = json_decode($datajs, 1);  // transforme en array
    		 $total_items_avec_taxe = 0;
     
    		 foreach ($data_decode_array['articles'] as $product) 
    		 	{
    				 $total = $product['prix'];                 //prix hors taxe
     
    				 foreach ($product['tax'] as $tax) 
    				 	{
    						$total += $tax['prix'];                //ajoute tax au prix hors taxe
    					}
     
    				$total_items_avec_taxe += $product['quantite'] * $total;
     
     
    		 	}
     
    		$total_items_avec_taxe = number_format($total_items_avec_taxe, 2);
     
     
    		// create child element -------------------|
    	$total_item_resume = $doc->createElement("total_item_resume");
    	$lavel1_resume->appendChild($total_item_resume);
     
    			// create text node =====================================||
    	$text_total_item_resume = $doc->createTextNode($total_items_avec_taxe);
    	$total_item_resume->appendChild($text_total_item_resume);
     
     
     
    	echo $doc->saveXML();
     
    	$doc->save("dom_xmltest.xml");

    Par contre je ne sais pas comment je peux inserer les lignes suivants pour faire la reste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // create child element with sub element-------------------| -------------------| 
    $chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
    //$chaque_item = $doc->createElement("chaque_item");
    //				$lavel1_resume->appendChild($chaque_item);
    // create child element with sub element-------------------| -------------------| | -------------------| 
    $prix = $chaque_item->appendChild($doc->createElement('prix'));
    //$prix = $doc->createElement("prix");
    //				$lavel1_resume->appendChild($product['prix']);
    // ou bien selon le taxe 	$lavel1_resume->appendChild($tax['prix']);
    // create text node
    $prix = $chaque_item->appendChild($doc->createTextNode('0.25'));
    // $text_prix = $doc->createTextNode("11.00");
    //			$lavel1_resume->appendChild($text_prix);
    // create child element with sub element-------------------| -------------------| | -------------------| 
    $quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    //$quantite = $doc->createElement("quantite");
    //				$lavel1_resume->appendChild($quantite);
    // create text node
    $quantite = $chaque_item->appendChild($doc->createTextNode('1'));
    //	  $text_quantite = $doc->createTextNode("un");
    //			$lavel1_resume->appendChild($text_quantite);
    // create child element with sub element-------------------| -------------------| | -------------------| 
    $nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    // create text node
    $nom_item = $chaque_item->appendChild($doc->createTextNode('taxe1'));
    // create child element with sub element-------------------| -------------------| | -------------------|
    Alors j'ai essayé avec cela :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // create child element with sub element-------------------|
    //$articles = $lavel1_resume->appendChild($doc->createElement('articles'));
    $articles = $doc->createElement("articles");
    $lavel1_resume->appendChild($articles);
    // create child element with sub element-------------------| -------------------| 
    $chaque_item = $articles->appendChild($doc->createElement('chaque_item'));	
    //$chaque_item = $doc->createElement("chaque_item");
    //				$lavel1_resume->appendChild($chaque_item);
    // create child element with sub element-------------------| -------------------| | -------------------| 
    $prix = $chaque_item->appendChild($doc->createElement('prix'));
    //$prix = $doc->createElement("prix");
    //				$lavel1_resume->appendChild($prix);
    foreach ($data_decode_array['articles'] as $product){
    	$prix = $chaque_item->appendChild($doc->createTextNode($product['prix']));  // prix d'un article
    	$quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    	$quantite = $chaque_item->appendChild($doc->createTextNode($product['quantite']));
    	$nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    	$nom_item = $chaque_item->appendChild($doc->createTextNode($product['nom_item']));
    	foreach ($product['tax'] as $tax){
    		$prix = $chaque_item->appendChild($doc->createTextNode($tax['prix'])); //// prix d'une taxe comme un article
    		$quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    		$quantite = $chaque_item->appendChild($doc->createTextNode($tax['quantite']));
    		$nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    		$nom_item = $chaque_item->appendChild($doc->createTextNode($tax['nom_item']));
    	}
    }
    // $text_prix = $doc->createTextNode("11.00");
    //			$lavel1_resume->appendChild($text_prix);
    // create child element with sub element-------------------| -------------------| | -------------------| 
    // create child element -------------------|
    echo $doc->saveXML();
    $doc->save("mon_dom_xml.xml");

    Comment je peux faire ? vous avez une idée ?

    Merci et bonne journée

  2. #2
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    En fait, ce que j’obtiens :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
        <chaque_item><prix/>2.00<quantite/>1<nom_item/>tomates0.25<quantite/>1<nom_item/>taxe10.50<quantite/>1<nom_item/>taxe21.00<quantite/>1<nom_item/>patates0.12<quantite/>1<nom_item/>taxe10.25<quantite/>1<nom_item/>taxe2</chaque_item>
      </articles>
    </resume>

    Ni beau ni correct

  3. #3
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    J'ai avancé un peu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    $articles = $doc->createElement("articles");
    $lavel1_resume->appendChild($articles);
    foreach ($data_decode_array['articles'] as $product){
            $chaque_item = $articles->appendChild($doc->createElement('chaque_item'));	
    	$lavel1_resume->appendChild($chaque_item);
    	$prix = $chaque_item->appendChild($doc->createElement('prix'));
    	$prix = $chaque_item->appendChild($doc->createTextNode($product['prix']));  // prix d'un article
    	$quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    	$quantite = $chaque_item->appendChild($doc->createTextNode($product['quantite']));
    	$nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    	$nom_item = $chaque_item->appendChild($doc->createTextNode($product['nom_item']));
    		foreach ($product['tax'] as $tax) {
    		        $chaque_item = $articles->appendChild($doc->createElement('chaque_item'));	
    			$prix = $chaque_item->appendChild($doc->createElement('prix'));
    			$prix = $chaque_item->appendChild($doc->createTextNode($tax['prix'])); //// prix d'une taxe comme un article
    			$quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    			$quantite = $chaque_item->appendChild($doc->createTextNode($tax['quantite']));
    			$nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    			$nom_item = $chaque_item->appendChild($doc->createTextNode($tax['nom_item']));
    		}
    	}
    Alors j'obtiens :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
        <chaque_item><prix/>2.00<quantite/>1<nom_item/>tomates</chaque_item>
        <chaque_item><prix/>0.25<quantite/>1<nom_item/>taxe1</chaque_item>
        <chaque_item><prix/>0.50<quantite/>1<nom_item/>taxe2</chaque_item>
        <chaque_item><prix/>1.00<quantite/>1<nom_item/>patates</chaque_item>
        <chaque_item><prix/>0.12<quantite/>1<nom_item/>taxe1</chaque_item>
        <chaque_item><prix/>0.25<quantite/>1<nom_item/>taxe2</chaque_item>
      </articles>
    </resume>

    [CODE]
    Alors il me reste de regrouper les taxes en deux items... Ensuite, il faudrait que je le formate mon fichier XML.

    Si vous avez des idées, je suis prenant...
    Merci

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    je ne t'ai pas tout solutionné mais je te donne une autre piste pour résoudre ta problématique. Il faut réserver DOMDocument aux gros traitements car c'est de l'artillerie lourde.

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    <?php
     
    $json = <<<'json'
    {
       "ville": "VERDUN",
       "articles": [
          {
             "prix": "2.00",
             "quantite": "1",
             "nom_item": "tomates",
             "tax": [
                {
                   "prix": "0.25",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.50",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          },
          {
             "prix": "1.00",
             "quantite": "1",
             "nom_item": "patates",
             "tax": [
                {
                   "prix": "0.12",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.75",
                   "quantite": "1",
                   "nom_item": "taxe3"
                }
             ]
          }
       ]
    }
    json;
     
    $data = json_decode($json, true);
     
    $xml  = <<<xml
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>{$data['ville']}</ville>
      <articles>
    xml;
     
    foreach ($data['articles'] as $v)
    {
        $xml .= <<<xml
    <chaque_item>
        <prix>{$v['prix']}</prix>
        <quantite>{$v['quantite']}</quantite>
        <nom_item>{$v['nom_item']}</nom_item>
    </chaque_item>
    xml;
    }
     
    $xml .= '</articles></resume>';
    $sxml = simplexml_load_string($xml);
     
    // output
    header('Content-Type: text/xml');
    header('Content-Type: application/xml');
    echo $sxml->asXML();

    Juste au cas où, je te signale que la lib simplexml est un sous-ensemble de DOMDocument

  5. #5
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    Merci rawsrc pour ton exemple...
    Par contre, mon problème vient de regrouper les taxes autrement :

    En fait, il faut que je trouve 1re taxe de 1er article + 1re taxe de 2e article, etc. pour 1re taxe
    et pour la 2e taxe de 1er article + 2e taxe de 2 articles, etc.

    Pour le moment, avec 2 essaie, je n'arrive pas...

    voici le 2e essai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    //...
    $articles = $doc->createElement("articles");
    $lavel1_resume->appendChild($articles);
    foreach ($data->articles as $objPproduct) {
    	$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));	
    	$prix = $chaque_item->appendChild($doc->createElement('prix'));
    	$prix = $chaque_item->appendChild($doc->createTextNode($objPproduct->prix));  // prix d'un article
    	$quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    	$quantite = $chaque_item->appendChild($doc->createTextNode($objPproduct->quantite));
    	$nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    	$nom_item = $chaque_item->appendChild($doc->createTextNode($objPproduct->nom_item));
    	// les taxes :			  
    	$taxes = (array)$objPproduct->tax;
    	$taxesPrice1 = $taxes[0]->prix;
    	$taxesPrice2 = $taxes[1]->prix; 
    	$taxesPrice12 = $taxesPrice1  + $taxesPrice2;
    	$taxesQuantity1 = $taxes[0]->quantite;
    	$taxesQuantity2 = $taxes[1]->quantite;
    	$taxesQuantity12 = $taxesQuantity1 + $taxesQuantity2 ;
    	$taxesDescription1 = $taxes[0]->nom_item;
    	$taxesDescription2 = $taxes[1]->nom_item;
    	$taxesDescription12 = $taxesDescription1 . '   ' . $taxesDescription2;      // il faut que je change ici : ce n'est pas logique par exemple "tax total 1"
    	$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));	
    	$prix = $chaque_item->appendChild($doc->createElement('prix'));
    	$prix = $chaque_item->appendChild($doc->createTextNode($taxesPrice12)); //// prix d'une taxe comme un article
    	$quantite = $chaque_item->appendChild($doc->createElement('quantite'));
    	$quantite = $chaque_item->appendChild($doc->createTextNode($taxesQuantity12));
    	$nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
    	$nom_item = $chaque_item->appendChild($doc->createTextNode($taxesDescription12));
    }
    et j'obtiens la même chose qui n'est pas bon :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
        <chaque_item><prix/>2.00<quantite/>1<nom_item/>tomates</chaque_item>
        <chaque_item><prix/>0.75<quantite/>2<nom_item/>taxe1   taxe2</chaque_item>
        <chaque_item><prix/>1.00<quantite/>1<nom_item/>patates</chaque_item>
        <chaque_item><prix/>0.37<quantite/>2<nom_item/>taxe1   taxe2</chaque_item>
      </articles>
    </resume>

    En fait il faut quelques choses mais je ne le vois pas du tout

  6. #6
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 888
    Points : 6 632
    Points
    6 632
    Par défaut
    Je pense qu'une bonne approche serait de transformer ton tableau de départ de telle manière que les diverses taxes apparaissent à la suite des produits et au même niveau. Donc d'obtenir ça dans un premier temps:
    Code text : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    Array
    (
        [ville] => VERDUN
        [articles] => Array
            (
                [0] => Array
                    (
                        [prix] => 2.00
                        [quantite] => 1
                        [nom_item] => tomates
                    )
     
                [1] => Array
                    (
                        [prix] => 1.00
                        [quantite] => 1
                        [nom_item] => patates
                    )
     
                [2] => Array
                    (
                        [prix] => 0.37
                        [quantite] => 2
                        [nom_item] => taxe1
                    )
     
                [3] => Array
                    (
                        [prix] => 1.25
                        [quantite] => 2
                        [nom_item] => taxe2
                    )
     
            )
     
    )

    Ce qui simplifiera la production de la structure XML souhaitée.

    On peut le faire comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $data = json_decode($json, true);
     
    $taxes = []; // on regroupe les taxes par nom dans un tableau à part
     
    foreach ($data['articles'] as &$article) {
        foreach ($article['tax'] as $tax) {
            $nom_item_tax = $tax['nom_item'];
     
            if (isset($taxes[$nom_item_tax])) {
                $taxes[$nom_item_tax]['quantite'] += $tax['quantite'];
                $taxes[$nom_item_tax]['prix'] += $tax['prix'];
            } else {
                $taxes[$nom_item_tax] = $tax;
            }
        }
        // et on les enlèves du tableau $data (c'est pas utile mais c'est plus beau)
        unset($article['tax']);   
    }
     
    // on trie le tableau $taxes par nom d'item (si éventuellement ils apparaissent dans le désordre)
    ksort($taxes);
     
    // puis on ajoute les items de $taxes à la suite des autres items de $data['articles'] 
    $data['articles'] = array_merge($data['articles'], $taxes);
    Ensuite, la raison pour laquelle tu obtiens <prix/>2.00 à la place de <prix>2.00</prix> est simple. Au lieu d'accrocher ton nœud texte au nœud de l'élément prix, tu l'accroches au nœud de l'élément chaque_item:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $prix = $chaque_item->appendChild($doc->createElement('prix'));
    $prix = $chaque_item->appendChild($doc->createTextNode($objPproduct->prix));
    Résultat tu obtiens une balise prix vide suivie d'un nœud texte qui se retrouve au même niveau qu'elle, c'est à dire enfant de chaque_item.

    Il suffit d'accrocher le nœud texte à son bon parent, c'est à dire le nœud prix:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $prix = $chaque_item->appendChild($doc->createElement('prix'));
    $prix->appendChild($doc->createTextNode($objPproduct->prix));
    Même chose pour quantite et nom_item.

    Concernant le choix de DOMDocument pour créer de zéro ton XML. Je dirais pourquoi pas car ça a l'avantage d'être un outil conçu pour produire du XML donc quelque soit l'ânerie qu'on laisse passer, on est sûr de se retrouver avec du XML bien formé (du XML quoi). Il a aussi l'avantage de permettre l'édition d'un document dans n'importe quel ordre. Par contre il faut avouer que ça produit un code bien verbeux et en quantité qui va de pair avec sa lenteur et son empreinte mémoire (la totalité de l'arbre doit être présent en mémoire). DOMDocument reste adapté tant que la quantité de données reste faible, mais ces défauts se font sentir dés que la quantité de données devient importante.

    Pour ce qui est de simpleXML, c'est exactement la même chose mais en moins verbeux, plus maniable. Par contre la lenteur est accentuée dans la mesure où il s'agit d'une surcouche de DOMDocument.

    Comme l'a suggéré rawsrc, une simple création de chaîne peut remplacer cette approche. Cette méthode a l'avantage d'être imbattable en terme de vitesse, par contre il faut savoir ce que l'on écrit car en cas d'erreur il n'y a pas de fermeture automatique de balises ou autres corrections et sécurités que peuvent procurer les outils XML. Pour produire une grande quantité de données avec une faible consommation de mémoire, on peut coupler cette approche avec une écriture en flux dans un fichier.

    Un bon compromis est l'utilisation de XMLWriter qui offre les avantages d'un outil conçu pour le XML tout en étant moins verbeux que DOMDocument, plus rapide et peu gourmand en mémoire. En revanche il faut tout écrire dans l'ordre. Il est assez facile à utiliser.

    En partant du tableau $data transformé précédemment:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // on calcule la somme à partir du nouveau tableau
    $somme = array_reduce($data['articles'], function ($c, $i) { return $c + $i['prix']*$i['quantite']; });
    // on force les deux décimales
    $somme = number_format($somme, 2);
     
    $xml = new XMLWriter();
    $xml->openURI('nomfichier.xml'); // on renseigne l'URI du fichier à créer
    $xml->setIndent(true);
    $xml->setIndentString("\t");
     
    $xml->startDocument('1.0','UTF-8');
    $xml->startElement('resume');
        $xml->startElement('ville'); // on mime l'indentation du fichier XML pour facilité la lecture
            $xml->text($data['ville']);
        $xml->endElement();
        $xml->startElement('total_item_resume');
            $xml->text($somme);
        $xml->endElement();
    foreach ($data['articles'] as $item) {
        $xml->startElement('chaque_item');
            $xml->startElement('prix');
                $xml->text($item['prix']);
            $xml->endElement();
            $xml->startElement('quantite');
                $xml->text($item['quantite']);
            $xml->endElement();
            $xml->startElement('nom_item');
                $xml->text($item['nom_item']);
            $xml->endElement();
        $xml->endElement();
    }
    $xml->endElement();
    $xml->endDocument();
    $xml->flush(); // on écrit le fichier et on libère la mémoire
    NB: pour les grosses quantités de données, il est également possible de faire des flushs périodiques, ce qui permet de garder une consommation de mémoire très faible.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Bonjour CosmoKnacki,
    Woow un grand merci pour ces explications bien détaillées...

    Je suis en train de lire et le comprendre... Je suis un peu lente.

    Il y a quelque chose que je ne comprenne pas comment tu peux transformer taxe en array :

    avec cela :

    Citation Envoyé par CosmoKnacki Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $data = json_decode($json, true);
     
    $taxes = []; // on regroupe les taxes par nom dans un tableau à part
     
    foreach ($data['articles'] as &$article) {
    J'ai un fatal error :

    Fatal error: Cannot use [] for reading in

    Est ce que tu voulais dire quelques choses comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     $data = json_decode($json, true);  // transforme en array
     
    $taxes = $data['tax'];
    Je vais continuer de lire cette réponse...

    Merci encore

  8. #8
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Ta version de PHP ne doit pas implémenter cette façon d'initialiser un tableau (et donc être inférieure à 5.4 annoncée dans le titre), modifies en

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Merci Bovino,

    Merci

    ma version de PHP c'est 5.5.11

    Alors j'ai changé le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $data_decode_array = json_decode($datajs, true); 
    $taxes = array(); // on regroupe les taxes par nom dans un tableau à part
    foreach ($data_decode_array['articles'] as &$article){
    	foreach ($article['tax'] as $tax){    // ----------------------------------------------------------------------line 115 
    		$nom_item_tax = $tax['nom_item'];
    		if (isset($taxes[$nom_item_tax])){
    			$taxes[$nom_item_tax]['quantite'] += $tax['quantite'];
    			$taxes[$nom_item_tax]['prix'] += $tax['prix'];
    		} 
    		else{
    			$taxes[$nom_item_tax] = $tax;
    		}
    	}
    	// et on les enlèves du tableau $data  ($data_decode_array) (c'est pas utile mais c'est plus beau)
    	unset($article['tax']);  
    }
    // on trie le tableau $taxes par nom d'item (si éventuellement ils apparaissent dans le désordre) Trie un tableau suivant les clés
    ksort($taxes);
    $prix = $chaque_item->appendChild($doc->createElement('prix'));
    $prix->appendChild($doc->createTextNode($taxes[$nom_item_tax]['prix'])); // total 1er ou 2e taxes TAXES    // ----------------------------------------------------------------------line 137 
    $prix = $chaque_item->appendChild($doc->createElement('quantite'));
    $prix->appendChild($doc->createTextNode($taxes[$nom_item_tax]['quantite']));    // ----------------------------------------------------------------------line 140 
    $prix = $chaque_item->appendChild($doc->createElement('nom_item'));
    $prix->appendChild($doc->createTextNode($taxes[$nom_item_tax]['nom_item']));   // ----------------------------------------------------------------------line 143
    J'ai des alertes

    Notice Undefined index: tax in on line 115
    Warning: Invalid argument supplied for foreach() in on line 115

    Notice: Undefined index: taxe2 in on line 137
    Notice: Undefined index: taxe2 in on line 140
    Notice: Undefined index: taxe2 in on line 143
    Du coup, mon fichier XML n'est pas bon

  10. #10
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 888
    Points : 6 632
    Points
    6 632
    Par défaut
    Pour ma part le json, une fois transformé en tableau avant toute modification a cet aspect là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    Array
    (
        [ville] => VERDUN
        [articles] => Array
            (
                [0] => Array
                    (
                        [prix] => 2.00
                        [quantite] => 1
                        [nom_item] => tomates
                        [tax] => Array
                            (
                                [0] => Array
                                    (
                                        [prix] => 0.25
                                        [quantite] => 1
                                        [nom_item] => taxe1
                                    )
     
                                [1] => Array
                                    (
                                        [prix] => 0.50
                                        [quantite] => 1
                                        [nom_item] => taxe2
                                    )
     
                            )
     
                    )
     
                [1] => Array
                    (
                        [prix] => 1.00
                        [quantite] => 1
                        [nom_item] => patates
                        [tax] => Array
                            (
                                [0] => Array
                                    (
                                        [prix] => 0.12
                                        [quantite] => 1
                                        [nom_item] => taxe1
                                    )
     
                                [1] => Array
                                    (
                                        [prix] => 0.75
                                        [quantite] => 1
                                        [nom_item] => taxe2
                                    )
     
                            )
     
                    )
     
            )
     
    )
    et provient de la chaîne json suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    {
       "ville": "VERDUN",
       "articles": [
          {
             "prix": "2.00",
             "quantite": "1",
             "nom_item": "tomates",
             "tax": [
                {
                   "prix": "0.25",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.50",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          },
          {
             "prix": "1.00",
             "quantite": "1",
             "nom_item": "patates",
             "tax": [
                {
                   "prix": "0.12",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.75",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          }
       ]
    }
    Vérifie que tu as bien la même structure de départ (qui est celle donnée dans le premier post). Vérifie aussi que tu ne t'es pas emmêlé les pinceaux avec les noms de variable.
    Une pratique assidue du print_r avec un peu de réflexion devrait venir assez vite à bout de ce problème d'index et en identifier l'origine.

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Exact... les miens sont comme les tiens :

    Mon fichier de json contient la même information que le tien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    {
       "ville": "VERDUN",
       "articles": [
          {
             "prix": "2.00",
             "quantite": "1",
             "nom_item": "tomates",
             "tax": [
                {
                   "prix": "0.25",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.50",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          },
          {
             "prix": "1.00",
             "quantite": "1",
             "nom_item": "patates",
             "tax": [
                {
                   "prix": "0.12",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.25",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          }
       ]
    }
    J'ai fait print_r sur mon array :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $datajs = "fruit.json"; // 3article (1 fruit + 2 taxe)
    $datajs = file_get_contents($datajs);
    $data = json_decode($datajs); //--------------------- objets
    //Calcule de prix total avec taxe
    //$data = json_decode($datajs);
    //$data_decode_array = json_decode($datajs, 1);  // transforme en array
    $data_decode_array = json_decode($datajs, true);  // transforme en array //--------------------- ARRAY
    print_r ($data_decode_array);
    exit();
    et j'obtiens la même information que ton array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    Array
    (
        [ville] => VERDUN
        [articles] => Array
            (
                [0] => Array
                    (
                        [prix] => 2.00
                        [quantite] => 1
                        [nom_item] => tomates
                        [tax] => Array
                            (
                                [0] => Array
                                    (
                                        [prix] => 0.25
                                        [quantite] => 1
                                        [nom_item] => taxe1
                                    )
     
                                [1] => Array
                                    (
                                        [prix] => 0.50
                                        [quantite] => 1
                                        [nom_item] => taxe2
                                    )
     
                            )
     
                    )
     
                [1] => Array
                    (
                        [prix] => 1.00
                        [quantite] => 1
                        [nom_item] => patates
                        [tax] => Array
                            (
                                [0] => Array
                                    (
                                        [prix] => 0.12
                                        [quantite] => 1
                                        [nom_item] => taxe1
                                    )
     
                                [1] => Array
                                    (
                                        [prix] => 0.25
                                        [quantite] => 1
                                        [nom_item] => taxe2
                                    )
     
                            )
     
                    )
     
            )
     
    )

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    En fait, voici la totalité du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
     
    <?
     
    header('Content-Type: text/xml');
    header('Content-Type: application/xml');
     
    $doc= new DOMDocument('1.0', 'UTF-8');
     
     
    //formatage
    $doc->preserveWhiteSpace = false;
    $doc->formatOutput = true;
     
     
    $datajs = "fruit.json"; // 4article (2 fruit + 2 taxe) 
     
    $datajs = file_get_contents($datajs); // recuperation du contenu
     
    $data = json_decode($datajs); //--------------------- transformation en objet
     
     
    $city= $data->ville;
    $total_items_avec_taxe = '0.0000';
     
     
    // create resume element
    $lavel1_resume = $doc->createElement("resume");
    $doc->appendChild($lavel1_resume);
     
     
    	// create child element -------------------|
    $ville = $doc->createElement("ville");
    $lavel1_resume->appendChild($ville);
     
    		// create text node =====================================||
    $text_ville = $doc->createTextNode($city);
    $ville->appendChild($text_ville);	
     
     
    //Calcule de prix total avec taxe
    		 $data_decode_array = json_decode($datajs, true);  // transforme en array //--------------------- ARRAY
     
    /*		 
    		 print_r ($data_decode_array);
    		 exit();
    		 
    */		 
     
     
    		 $total_items_avec_taxe = 0;
     
    		 foreach ($data_decode_array['articles'] as $product) 
    		 	{
    				 $total = $product['prix'];                 //prix hors taxe
     
    				 foreach ($product['tax'] as $tax) 
    				 	{
    						$total += $tax['prix'];                //ajoute tax au prix hors taxe
    					}
     
    				$total_items_avec_taxe += $product['quantite'] * $total;
     
     
    		 	}
     
    		$total_items_avec_taxe = number_format($total_items_avec_taxe, 2);
     
     
    		// create child element -------------------|
    	$total_item_resume = $doc->createElement("total_item_resume");
    	$lavel1_resume->appendChild($total_item_resume);
     
    			// create text node =====================================||
    	$text_total_item_resume = $doc->createTextNode($total_items_avec_taxe);
    	$total_item_resume->appendChild($text_total_item_resume);
     
    	$articles = $doc->createElement("articles");
    	$lavel1_resume->appendChild($articles);
     
     
     
     
    	//Calcule le prix de produits sans taxes HORS TAX
    	foreach ($data->articles as $objPproduct) //1er foreach objet
    		{
    			$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
     
    			$prix = $chaque_item->appendChild($doc->createElement('prix'));
    			$prix->appendChild($doc->createTextNode($objPproduct->prix)); // prix d'un article HORS TAXES
     
    			$prix = $chaque_item->appendChild($doc->createElement('quantite'));
    			$prix->appendChild($doc->createTextNode($objPproduct->quantite));
     
    			$prix = $chaque_item->appendChild($doc->createElement('nom_item'));
    			$prix->appendChild($doc->createTextNode($objPproduct->nom_item));
     
     
     
     
     
    			$taxes = array(); // on regroupe les taxes par nom dans un tableau à part
     
     
    			foreach ($data_decode_array['articles'] as &$article) 
    			{
    				foreach ($article['tax'] as $tax) 
    					{
    						$nom_item_tax = $tax['nom_item'];
     
    						if (isset($taxes[$nom_item_tax])) 
    							{
    								$taxes[$nom_item_tax]['quantite'] += $tax['quantite'];
    								$taxes[$nom_item_tax]['prix'] += $tax['prix'];
    							} 
    						else 
    							{
    								$taxes[$nom_item_tax] = $tax;
    							}
    					}
    				// et on les enlèves du tableau $data_decode_array) 
    				unset($article['tax']);  
    			}
     
    			// on trie le tableau $taxes par nom d'item Trie un tableau suivant les clés
    			ksort($taxes);
     
    			$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
     
    			$prix = $chaque_item->appendChild($doc->createElement('prix'));
    			$prix->appendChild($doc->createTextNode($taxes[$nom_item_tax]['prix'])); // total 1er ou 2e taxes TAXES
     
    			$prix = $chaque_item->appendChild($doc->createElement('quantite'));
    			$prix->appendChild($doc->createTextNode($taxes[$nom_item_tax]['quantite']));
     
    			$prix = $chaque_item->appendChild($doc->createElement('nom_item'));
    			$prix->appendChild($doc->createTextNode($taxes[$nom_item_tax]['nom_item']));
     
     
     
     
     
     
    		} //FIN 1er foreach objet
     
     
     
     
    echo $doc->saveXML();
     
    $doc->save("monFichierdom_xml.xml");
    avec cela j'obtiens un fichier XML :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
        <chaque_item>
          <prix>2.00</prix>
          <quantite>1</quantite>
          <nom_item>tomates</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>0.75</prix>
          <quantite>2</quantite>
          <nom_item>taxe2</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>1.00</prix>
          <quantite>1</quantite>
          <nom_item>patates</nom_item>
        </chaque_item>
        <chaque_item>
          <prix></prix>
          <quantite></quantite>
          <nom_item></nom_item>
        </chaque_item>
      </articles>
    </resume>

    et avec les alertes dont j'ai cité ci-dessus.

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Donc je n'arrive pas récupérer 'taxe1' et de mettre dans mon fichier XML

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    En fait, je vois que 1er enregistrement (de taxe) s'écrase par la 2e

    J'ai mis un break et je vois la 1re taxe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    foreach ($data_decode_array['articles'] as &$article){
    	foreach ($article['tax'] as $tax){
    		$nom_item_tax = $tax['nom_item'];
    		if (isset($taxes[$nom_item_tax])){
    			$taxes[$nom_item_tax]['quantite'] += $tax['quantite'];
    			$taxes[$nom_item_tax]['prix'] += $tax['prix'];
    		} 
    		else{
    			$taxes[$nom_item_tax] = $tax;
    		}break; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    	}
    	// et on les enlèves du tableau $data_decode_array) 
    	unset($article['tax']);  
    }
    et voici ce que j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
        <chaque_item>
          <prix>2.00</prix>
          <quantite>1</quantite>
          <nom_item>tomates</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>0.37</prix>
          <quantite>2</quantite>
          <nom_item>taxe1</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>1.00</prix>
          <quantite>1</quantite>
          <nom_item>patates</nom_item>
        </chaque_item>
        <chaque_item>
          <prix></prix>
          <quantite></quantite>
          <nom_item></nom_item>
        </chaque_item>
      </articles>
    </resume>
    Que je dois faire pour ne pas l’écraser ?

    merci

  15. #15
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 888
    Points : 6 632
    Points
    6 632
    Par défaut
    Tu m'étonnes que ça marche pas! Tu as placé la création du tableau en plein dans une boucle foreach!

    Donc, réécrit tout ton code de zéro avec cette structure:

    1) création du tableau associatif à partir de la chaîne json
    2) transformation du tableau
    3) génération du xml (là et pas avant!). On boucle sur le tableau pour les articles

    Et surtout fait bien attention à ce que tu écris, ne fait pas de copier/coller au petit bonheur la chance.

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Salut CosmoKnacki,

    Tu as raison... J'étais un peu trop...

    Citation Envoyé par CosmoKnacki Voir le message
    Tu m'étonnes que ça marche pas! Tu as placé la création du tableau en plein dans une boucle foreach!
    Et surtout fait bien attention à ce que tu écris, ne fait pas de copier/coller au petit bonheur la chance.
    Alors j'ai fait et ça marche comme je veux :

    Voici ce que j'obtiens...
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?xml version="1.0" encoding="UTF-8"?>
    <resume>
      <ville>VERDUN</ville>
      <total_item_resume>4.12</total_item_resume>
      <articles>
        <chaque_item>
          <prix>2.00</prix>
          <quantite>1</quantite>
          <nom_item>tomates</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>1.00</prix>
          <quantite>1</quantite>
          <nom_item>patates</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>0.37</prix>
          <quantite>1</quantite>
          <nom_item>taxe1</nom_item>
        </chaque_item>
        <chaque_item>
          <prix>0.75</prix>
          <quantite>1</quantite>
          <nom_item>taxe2</nom_item>
        </chaque_item>
      </articles>
    </resume>
    Et un grand merci.
    Voici mes codes selon vos informations et selon mes compréhensions (mes capacités limitées) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    //création du tableau associatif à partir du fichyier json
    /* ======================================================= */
     
     
    		//$datajs = "fruit1.json"; // taxew plus visible
    		$datajs = "fruit.json"; // 4article (2 fruit + 2 taxe) 
     
     
     
    		$datajs = file_get_contents($datajs);
     
     
    		$data_decode_array = json_decode($datajs, true);  // transforme en array //--------------------- ARRAY///////////////////////////////
     
     
    		 //print_r ($data_decode_array);
    		 //var_dump($data_decode_array);
    		// exit();
     
    		// on regroupe les taxes par nom dans un tableau à part
    		/* ======================================================= */
    		$taxes = array(); 
     
     
    		foreach ($data_decode_array['articles'] as &$article) 
    		{
    			foreach ($article['tax'] as $tax) 
    				{
    					$nom_item_tax = $tax['nom_item'];
     
    					if (isset($taxes[$nom_item_tax])) 
    						{
    							$taxes[$nom_item_tax]['quantite'] += $tax['quantite'];
    							$taxes[$nom_item_tax]['prix'] += $tax['prix'];
    						} 
    					else 
    						{
    							$taxes[$nom_item_tax] = $tax;
    						}
    						//break;
    				}
    			// et on les enlèves du tableau $data_decode_array) 
    			unset($article['tax']);  
    		}
     
    		// on trie le tableau $taxes par nom d'item Trie un tableau suivant les clés
    		ksort($taxes);
     
    		// Fusionne plusieurs tableaux en un seul : les items de $taxes à la suite des autres items de $data['articles'] 
    		$data_decode_array['articles'] = array_merge($data_decode_array['articles'], $taxes);
     
    			//print_r ($data_decode_array);
    		//var_dump($data_decode_array);
    					//var_dump($data_decode_array['articles']);
     
    		$var_ville = $data_decode_array['ville'];
     
    		$var_taxe1__nom_item = $data_decode_array['articles']['taxe1']['nom_item'];
    		$var_taxe1__prix = $data_decode_array['articles']['taxe1']['prix'];
     
    		$var_taxe2__nom_iteme = $data_decode_array['articles']['taxe2']['nom_item'];
    		$var_taxe2__prix = $data_decode_array['articles']['taxe2']['prix'];
     
    		$var_taxe__quantite = 1; // quantitie tax par categorie est toujours 1!!!!
     
     
     
    		//Calcule de prix total avec taxe
    		/* ======================================================= */
     
    		$data_array_prix_total = json_decode($datajs, true);  // transforme en array //--------------------- ARRAY///////////////////////////////
     
     
     
     
    		$total_items_avec_taxe = 0;
     
    		 foreach ($data_array_prix_total['articles'] as $product) 
    			{
    				 $total = $product['prix'];                 //prix hors taxe
     
    				 foreach ($product['tax'] as $taxProduct) 
    					{
    						$total += $taxProduct['prix'];                //ajoute tax au prix hors taxe
    					}
     
    				$total_items_avec_taxe += $product['quantite'] * $total;
     
     
    			}
     
    		$total_items_avec_taxe = number_format($total_items_avec_taxe, 2);
     
     
    		//------------ XML-------------------------------------------
    		/* ======================================================= */
    		header('Content-Type: text/xml');
    		header('Content-Type: application/xml');
     
    		$doc= new DOMDocument('1.0', 'UTF-8');
     
     
    		//formatage
    		$doc->preserveWhiteSpace = false;
    		$doc->formatOutput = true;
     
     
    		//------------ XML niveau 1   resume  -----------------------
    		/* ======================================================= */
    		$lavel1_resume = $doc->createElement("resume");
    		$doc->appendChild($lavel1_resume);
     
    				// create child element -------------------| ville
    		$ville = $doc->createElement("ville");
    		$lavel1_resume->appendChild($ville);
    				// create text node =====================================|ville
    		$text_ville = $doc->createTextNode($var_ville);
    		$ville->appendChild($text_ville);
     
     
     
    		$total_item_resume = $doc->createElement("total_item_resume");
    		$lavel1_resume->appendChild($total_item_resume);
    		$text_total_item_resume = $doc->createTextNode($total_items_avec_taxe);
    		$total_item_resume->appendChild($text_total_item_resume);
     
     
    		//------------ XML niveau 2 articles -----------------------
    		/* ======================================================= */		
    		$articles = $doc->createElement("articles");
    		$lavel1_resume->appendChild($articles);
     
     
    		//------------ XML niveau 3 chaque_item  -- Produits   -----
    		/* ======================================================= */
    		$data_object = json_decode($datajs); //--------------------- objets --------------------- object///////////////////////////////
    		foreach ($data_object->articles as $objPproduct)
    		{
    			$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
     
    			$prix = $chaque_item->appendChild($doc->createElement('prix'));
    			$prix->appendChild($doc->createTextNode($objPproduct->prix)); // prix d'un article HORS TAXES
     
    			$prix = $chaque_item->appendChild($doc->createElement('quantite'));
    			$prix->appendChild($doc->createTextNode($objPproduct->quantite));
     
    			$prix = $chaque_item->appendChild($doc->createElement('nom_item'));
    			$prix->appendChild($doc->createTextNode($objPproduct->nom_item));
     
    		}
     
    		//------------ XML niveau 3 chaque_item  -- TAXES 1  -------
    		/* ======================================================= */		
    		$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
     
    		$prix = $chaque_item->appendChild($doc->createElement('prix'));
    		$prix->appendChild($doc->createTextNode($var_taxe1__prix)); // total 1er ou 2e taxes TAXES
     
    		$prix = $chaque_item->appendChild($doc->createElement('quantite'));
    		$prix->appendChild($doc->createTextNode($var_taxe__quantite));
     
    		$prix = $chaque_item->appendChild($doc->createElement('nom_item'));
    		$prix->appendChild($doc->createTextNode($var_taxe1__nom_item));
     
     
    		//------------ XML niveau 3 chaque_item  -- TAXES 2  -------
    		/* ======================================================= */		
    		$chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
     
    		$prix = $chaque_item->appendChild($doc->createElement('prix'));
    		$prix->appendChild($doc->createTextNode($var_taxe2__prix)); // total 1er ou 2e taxes TAXES
     
    		$prix = $chaque_item->appendChild($doc->createElement('quantite'));
    		$prix->appendChild($doc->createTextNode($var_taxe__quantite));
     
    		$prix = $chaque_item->appendChild($doc->createElement('nom_item'));
    		$prix->appendChild($doc->createTextNode($var_taxe2__nom_iteme));
     
     
     
    echo $doc->saveXML();
     
    $doc->save("myNewDom_xml.xml");
    Je suis sûr qu'il y a une autre façon de coder, mieux que cela plus épuré que le mien...

    Alors si vous avez d'accord sur ce code, j'aimerais bien savoir si vraiment je dois faire en XMLWriter au lieu que DOMDocument ?

    Merci encore

  17. #17
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 888
    Points : 6 632
    Points
    6 632
    Par défaut
    C'est déjà bien mieux plus clair, et surtout ça fonctionne, mais il y a quelque chose que tu n'as pas vu:

    Tout va bien jusqu'à la ligne 136. Il n'est pas nécessaire de décoder une nouvelle fois le json! Toutes les informations nécessaires sont déjà dans $data_decode_array. Le but de la transformation du tableau $data_decode_array n'est pas seulement de permettre les différents calculs (additions des taxes, somme générale). Son autre but est de permettre de générer facilement tous les enfants du nœud "articles" sans avoir à se demander s'il s'agit d'une tomate, d'une patate ou d'une taxe.

    Donc au lieu d'écrire tout ce qu'il y a de la ligne 136 à 177, il suffit de faire une boucle sur les articles de $data_decode_array, car dans ce tableau modifié, désormais une taxe est au même niveau qu'une patate ou une tomate:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    foreach($data_decode_array['articles'] as $objPproduct) {
        $chaque_item = $articles->appendChild($doc->createElement('chaque_item'));
     
        $prix = $chaque_item->appendChild($doc->createElement('prix'));
        $prix->appendChild($doc->createTextNode($objPproduct['prix']));
     
        $quantite = $chaque_item->appendChild($doc->createElement('quantite'));
        $quantite->appendChild($doc->createTextNode($objPproduct['quantite']));
     
        $nom_item = $chaque_item->appendChild($doc->createElement('nom_item'));
        $nom_item->appendChild($doc->createTextNode($objPproduct['nom_item']));
    }

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    il suffit de faire une boucle sur les articles de $data_decode_array, car dans ce tableau modifié, désormais une taxe est au même niveau qu'une patate ou une tomate:
    C'est vraiment excellent.... c'est plus court avec ta boucle...

    Un grand merci.

    J'ai une autre question sur la même sujet, mais légèrement différente... Je me demande si je dois ouvrir un autre post ou on peut continuer ici.

    Comment je peux supprimer un article dans un json/array ?

    Voici mon nouveau json :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    {
       "ville": "VERDUN",
       "articles": [
          {
    		 "prix": "2.00",
    		 "couleur": "rouge",
             "quantite": "1",
             "nom_item": "tomates",
             "tax": [
                {
                   "prix": "0.25",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.50",
                   "quantite": "1",
                   "nom_item": "taxe2"
                }
             ]
          },
          {
             "prix": "1.00",
    		  "couleur": "jaune",
             "quantite": "1",
             "nom_item": "patates",
             "tax": [
                {
                   "prix": "0.12",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.75",
                   "quantite": "1",
                   "nom_item": "taxe3"
                }
             ]
          },
          {
             "prix": "3.00",
    		  "couleur": "rouge",
             "quantite": "1",
             "nom_item": "betteraves",
             "tax": [
                {
                   "prix": "0.22",
                   "quantite": "1",
                   "nom_item": "taxe1"
                },
                {
                   "prix": "0.85",
                   "quantite": "1",
                   "nom_item": "taxe3"
                }
             ]
          }
       ]
    }
    Comme tu vois, il y a un nouvel élément : couleur
    et il y a 3 articles.

    J'aimerais bien choisir seulement les articles en rouge

    Donc il faut que j'obtienne un array comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    Array
    (
        [ville] => VERDUN
        [articles] => Array
            (
                [0] => Array
                    (
                        [prix] => 2.00
    					[couleur] => rouge
                        [quantite] => 1
                        [nom_item] => tomates
                        [tax] => Array
                            (
                                [0] => Array
                                    (
                                        [prix] => 0.25
                                        [quantite] => 1
                                        [nom_item] => taxe1
                                    )
     
                                [1] => Array
                                    (
                                        [prix] => 0.50
                                        [quantite] => 1
                                        [nom_item] => taxe2
                                    )
     
                            )
     
                    )
     
                [1] => Array
                    (
                        [prix] => 3.00
    					[couleur] => rouge
                        [quantite] => 1
                        [nom_item] => betteraves
                        [tax] => Array
                            (
                                [0] => Array
                                    (
                                        [prix] => 0.22
                                        [quantite] => 1
                                        [nom_item] => taxe1
                                    )
     
                                [1] => Array
                                    (
                                        [prix] => 0.85
                                        [quantite] => 1
                                        [nom_item] => taxe2
                                    )
     
                            )
     
                    )
     
            )
     
    )
    Alors comment je peux sélectionner seulement une couleur ?

    Merci encore et s'il faut je peux ouvrir un autre post pour cela...

  19. #19
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Bonjour,

    Je l'ai trouvé... La solution...

    Voici mes rectification
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    		//la ligne 13 :
    		//$data_decode_array = json_decode($datajs, true);  // transforme en array //--------------------- ARRAY///////////////////////////////    la ligne 13
     
    		$data_venu_decode_array = json_decode($datajs, true); // NEW   transforme en array //--------------------- ARRAY///////////////////////////////
     
    		foreach ($data_venu_decode_array['articles'] as &$key_couleur) // NEW 
    		{
    			if($key_fruits['couleur'] == 'rouge') // NEW 
    			$data_decode_array[] = $key_couleur; // NEW 
    		}
     
     
    		//la ligne 25 :
    		//foreach ($data_decode_array['articles'] as &$article) 
    		foreach ($data_decode_array as &$article) //new
     
     
     
    		//la ligne 50
    		// Fusionne plusieurs tableaux en un seul : les items de $taxes à la suite des autres items de $data['articles'] 
    		//$data_decode_array['articles'] = array_merge($data_decode_array['articles'], $taxes);
    		$data_decode_array = array_merge($data_decode_array, $taxes);  // new
     
     
     
    		la ligne 56 :
    		//$var_ville = $data_decode_array['ville'];
    		$var_ville = $data_venu_decode_array['ville'];   // new
     
     
    		// etc
    		//$var_taxe1__nom_item = $data_decode_array['articles']['taxe1']['nom_item'];
    		//var_taxe1__prix = $data_decode_array['articles']['taxe1']['prix'];
     
    		 $var_taxe1__nom_item = $data_decode_array['taxe1']['nom_item'];// new
    		$var_taxe1__prix = $data_decode_array['taxe1']['prix']; // new
    En fait, avec le code suivant je sélectionne ce que je veux : Rouge

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    		foreach ($data_venu_decode_array['articles'] as &$key_couleur) // NEW 
    		{
    			if($key_fruits['couleur'] == 'rouge') // NEW 
    			$data_decode_array[] = $key_couleur; // NEW 
    		}
    Merci encore vos aides et patience...

  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    316
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 316
    Points : 155
    Points
    155
    Par défaut
    Merci encore et Merci aussi à CosmoKnacki (et Bovino et Rawsrc)
    je ferme ce post si vous êtes d'accord

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Personnaliser la documentation XML générée par Visual Studio
    Par olivier34 dans le forum Visual Studio
    Réponses: 7
    Dernier message: 15/09/2009, 15h40
  2. comment transformer tableau html en xml tag ?
    Par lisadev dans le forum Format d'échange (XML, JSON...)
    Réponses: 0
    Dernier message: 21/10/2008, 14h25
  3. [AJAX] Transfert de document xml généré par php
    Par flash_math dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 05/11/2007, 12h03
  4. Réponses: 4
    Dernier message: 23/06/2005, 12h44
  5. pb formatage document XML généré par un dom tree
    Par lionel69 dans le forum APIs
    Réponses: 11
    Dernier message: 17/10/2002, 09h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo