Search code examples
phpxmlimportmergeload

Insert value in xml file when field match


i need to take field MASSIMALE from massimali.xml and put it on all massimale fiels on esercizi.xml where field UTENTE and ESERCIZIO match : eg I have one MASSIMALE to insert in many row of the same exercise. in your solution the value of the MASSIMALE is loaded only in the first exercise and not in all the exercises with the same name and the same user

<?xml version="1.0"?>
<sessioni>
  <sessione position="1">
    <id>1739616101355231</id>
    <index>1</index>
    <nome_sessione>3</nome_sessione>
    <utente>USER1</utente>    **<- MATCH WITH USER1 IN massimali.xml**
    <esercizio>BENCH PRESS</esercizio> **<- MATCH WITH USER1 IN massimali.xml**
    <rep_sessione>1</rep_sessione>
    <percent_sessione>50</percent_sessione>
    <massimale>100</massimale> <- LOAD FROM massimali.xml

Thank You

esercizi.xml

<?xml version="1.0"?>
<sessioni>
  <sessione position="1">
    <id>1739616101355231</id>
    <index>1</index>
    <nome_sessione>3</nome_sessione>
    <utente>USER1</utente>
    <esercizio>BENCH PRESS</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>50</percent_sessione>
    <massimale/>
  </sessione>
  <sessione position="2">
    <id>1739616101355231</id>
    <index>2</index>
    <nome_sessione>3</nome_sessione>
    <utente>USER1</utente>
    <esercizio>BENCH PRESS</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>65</percent_sessione>
    <massimale/>
  </sessione>
  <sessione position="3">
    <id>1739616101355231</id>
    <index>3</index>
    <nome_sessione>3</nome_sessione>
    <utente>USER1</utente>
    <esercizio>BENCH PRESS</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>75</percent_sessione>
    <massimale/>
  </sessione>
  <sessione position="4">
    <id>1739616101355231</id>
    <index>4</index>
    <nome_sessione>3</nome_sessione>
    <utente>USER1</utente>
    <esercizio>BENCH PRESS</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>80</percent_sessione>
    <massimale/>
  </sessione>
  <sessione position="5">
    <id>1739720496368387</id>
    <index>5</index>
    <nome_sessione>1</nome_sessione>
    <utente>USER2</utente>
    <esercizio>BACK SQUAT</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>65</percent_sessione>
    <massimale/>
  </sessione>
  <sessione position="6">
    <id>1739720496368387</id>
    <index>6</index>
    <nome_sessione>1</nome_sessione>
    <utente>USER2</utente>
    <esercizio>BACK SQUAT</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>75</percent_sessione>
    <massimale/>
  </sessione>
  <sessione position="7">
    <id>1739720496368387</id>
    <index>7</index>
    <nome_sessione>1</nome_sessione>
    <utente>USER2</utente>
    <esercizio>BACK SQUAT</esercizio>
    <rep_sessione>1</rep_sessione>
    <percent_sessione>85</percent_sessione>
    <massimale/>
  </sessione>
</sessioni>

massimali.xml


<?xml version="1.0"?>
<massimali>
  <atleta position="1">
    <id>1739616101355231</id>
    <utente>USER1</utente>
    <esercizio>BENCH PRESS</esercizio>
    <massimale>100</massimale>
    <data>2022-07-30</data>
  </atleta>
  <atleta position="2">
    <id>1739720496368387</id>
    <utente>USER1</utente>
    <esercizio>BACK SQUAT</esercizio>
    <massimale>80</massimale>
    <data>2022-07-30</data>
  </atleta>
  <atleta position="3">
    <id>1739720496368387</id>
    <utente>USER2</utente>
    <esercizio>BACK SQUAT</esercizio>
    <massimale>100</massimale>
    <data>2022-07-30</data>
  </atleta>
  <atleta position="4">
    <id>1739616101355231</id>
    <utente>USER2</utente>
    <esercizio>BENCH PRESS</esercizio>
    <massimale>95</massimale>
    <data>2022-07-30</data>
  </atleta>
</massimali>


Solution

  • Since you're dealing with two xml files, you should be using an xml parser with xpath, like this:

    #load the files
    $ese = simplexml_load_file("esercizi.xml");
    $mas = simplexml_load_file("massimali.xml");
    
    #load each file into xml
    $masdoc = new SimpleXMLElement($mas);
    $esedoc = new SimpleXMLElement($ese);
    
    #get the athletes in the first file
    $masatletas = $masdoc->xpath('//atleta');    
    
    #now loop through them:
    foreach($masatletas as $masatleta) {
     $masute =  $masatleta->xpath('.//utente')[0];
     $masese = $masatleta->xpath('.//esercizio')[0];
     $masmas = $masatleta->xpath('.//massimale')[0];
    
     #this is the critical directive: look for the each artist in the other file
     #and check to see if the credentials are the same:     
     $target = $esedoc->xpath("//sessione[.//utente= '{$masute}'][.//esercizio= '{$masese}']");
    
     if (count($target) == 1) {
               #if so, change the value to fit that of its equivalent in the first:
               $newmas = $target[0]->xpath('.//massimale/text()')[0];
               $newmas[0] = $masmas;
               }
    }
    echo $esedoc->asXml();
    

    EDIT:

    For your modified files, change the for loop as follows:

    foreach($masatletas as $masatleta) {
            $masute =  $masatleta->xpath('.//utente/.')[0];
            $masese = $masatleta->xpath('.//esercizio/.')[0];
            $masmas = $masatleta->xpath('.//massimale/.')[0];
            $targets= $esedoc->xpath("//sessione[.//utente = '{$masute}'][.//esercizio = '{$masese}']");
            foreach ($targets as $target){
                        $newmas = $target->xpath('.//massimale')[0];
                        $newmas[0] = $masmas;
                        };
        };
    

    and it should work.