2016-01-27 1 views
1

Je dois analyser les données du fichier XML en CSV en utilisant PHP. J'ai écrit le code en PHP, il obtient seulement quelques détails et il n'extrait pas les détails du noeud s'il a des enfants. Je suis en train de tester avec une plus petite partie de XML, le fichier d'origine a une très grande quantité de données autour de 20.000 nœuds personnes. Voici mes données XML -> list.xml.Ne pas obtenir toutes les données des nœuds lors de l'analyse de XML en CSV en utilisant PHP

<persons> 
    <person> 
     <id>326324</id> 
     <lastName>ABC</lastName> 
     <firstName>XYZ</firstName> 
     <middleName>PQR</middleName> 
     <preferredfirstName></preferredfirstName> 
     <details> 
      <JobTitle>Engineer</JobTitle> 
      <Dept>Healthcare</Dept> 
      <emp_position_no>PT0970</emp_position_no> 
      <emp_class_code>AJ</emp_class_code> 
      <emp_class_desc>Developer</emp_class_desc> 
      <emp_rank></emp_rank> 
      <CA_AddrStreet></CA_AddrStreet> 
      <CA_AddrCity></CA_AddrCity> 
      <CA_AddrState></CA_AddrState> 
      <CA_AddrZip></CA_AddrZip> 
      <CA_Phone></CA_Phone> 
      <EmployeeEmail>[email protected]</EmployeeEmail> 
     </details> 
     <Projects> 
      <subj_crse>MKTG 311</subj_crse> 
      <subj_crse>MKTG 428</subj_crse> 
     </Projects> 
    </person> 
    <person> 
     <id>956197</id> 
     <lastName>YTRG</lastName> 
     <firstName>WDES</firstName> 
     <middleName>BVCX</middleName> 
     <preferredfirstName></preferredfirstName> 
     <details> 
      <JobTitle>TECHNICIAN</JobTitle> 
      <Dept>Education</Dept> 
      <emp_position_no>PT1010</emp_position_no> 
      <emp_class_code>AJ</emp_class_code> 
      <emp_class_desc>Technician</emp_class_desc> 
      <emp_rank></emp_rank> 
      <CA_AddrStreet></CA_AddrStreet> 
      <CA_AddrCity></CA_AddrCity> 
      <CA_AddrState></CA_AddrState> 
      <CA_AddrZip></CA_AddrZip> 
      <CA_Phone></CA_Phone> 
      <EmployeeEmail>[email protected]</EmployeeEmail> 
     </details> 
     <Projects> 
      <subj_crse>TCHCS 321</subj_crse> 
     </Projects> 
    </person> 
</persons> 

Je suis en mesure de récupérer les données jusqu'à ce que le noeud preferredfirstName et après que, depuis le noeud détails a des enfants plus que je suis incapable d'en extraire les données. Ci-dessous mon code PHP:

$xml = simplexml_load_file('list.xml'); 
    $i = 1;   
    $values = [];  

    $columns = array('id', 'lastName', 'firstName', 
        'middleName', 'preferredfirstName', 'details', 'Projects'); 

    $fs = fopen('ODU.csv', 'w'); 
    fputcsv($fs, $columns);  
    fclose($fs); 

    $node = $xml->xpath('//person'); 

    foreach ($node as $n) {   


     $child = $xml->xpath('//person['.$i.']/*');  

     foreach ($child as $value) { 
      $values[] = $value;   
     } 


     $fs = fopen('test.csv', 'a'); 
     fputcsv($fs, $values);  
     fclose($fs); 

     $values = [];  
     $i++;    
    } 

J'ai besoin de la sortie dans le fichier CSV avec les détails de chaque nœud dans colums séparés comme ci-dessous: enter image description here

Répondre

0

Je n'utilise jamais simplexml mais je suppose que vous pourriez facilement atteindre le même J'utilise ça plutôt que DOMDocument comme ci-dessous - je ne vois pas, dans ce cas, de réel besoin pour la requête XPath - tout est assez simple. J'espère que vous serez en mesure de faire usage de ce qui suit en quelque sorte.

$strxml='<persons> 
      <person> 
       <id>326324</id> 
       <lastName>ABC</lastName> 
       <firstName>XYZ</firstName> 
       <middleName>PQR</middleName> 
       <preferredfirstName></preferredfirstName> 
       <details> 
        <JobTitle>Engineer</JobTitle> 
        <Dept>Healthcare</Dept> 
        <emp_position_no>PT0970</emp_position_no> 
        <emp_class_code>AJ</emp_class_code> 
        <emp_class_desc>Developer</emp_class_desc> 
        <emp_rank></emp_rank> 
        <CA_AddrStreet></CA_AddrStreet> 
        <CA_AddrCity></CA_AddrCity> 
        <CA_AddrState></CA_AddrState> 
        <CA_AddrZip></CA_AddrZip> 
        <CA_Phone></CA_Phone> 
        <EmployeeEmail>[email protected]</EmployeeEmail> 
       </details> 
       <Projects> 
        <subj_crse>MKTG 311</subj_crse> 
        <subj_crse>MKTG 428</subj_crse> 
       </Projects> 
      </person> 
      <person> 
       <id>956197</id> 
       <lastName>YTRG</lastName> 
       <firstName>WDES</firstName> 
       <middleName>BVCX</middleName> 
       <preferredfirstName></preferredfirstName> 
       <details> 
        <JobTitle>TECHNICIAN</JobTitle> 
        <Dept>Education</Dept> 
        <emp_position_no>PT1010</emp_position_no> 
        <emp_class_code>AJ</emp_class_code> 
        <emp_class_desc>Technician</emp_class_desc> 
        <emp_rank></emp_rank> 
        <CA_AddrStreet></CA_AddrStreet> 
        <CA_AddrCity></CA_AddrCity> 
        <CA_AddrState></CA_AddrState> 
        <CA_AddrZip></CA_AddrZip> 
        <CA_Phone></CA_Phone> 
        <EmployeeEmail>[email protected]</EmployeeEmail> 
       </details> 
       <Projects> 
        <subj_crse>TCHCS 321</subj_crse> 
       </Projects> 
      </person> 
     </persons>'; 

$dom=new DOMDocument; 
$dom->loadXML($strxml); 
/* 
    to load a file rather than a string of xml 
    ------------------------------------------ 
    $dom->load(realpath('list.xml')); 
*/ 



/* file handles */ 
$output=__DIR__.'\odu.csv'; 
$tmp=tempnam(sys_get_temp_dir(), 'csv'); 
$handle=fopen($tmp, 'r+'); 



$col=$dom->getElementsByTagName('person'); 

if($col){ 
    foreach($col as $person){ 
     if($person->nodeType==XML_ELEMENT_NODE && $person->hasChildNodes()){ 

      /* arrays to hold data */ 
      $row=array(); 
      $cols=array(); 

      foreach($person->childNodes as $node) { 

       if($node->nodeType==XML_ELEMENT_NODE){ 

        if($node->hasChildNodes() && $node->childNodes->length > 1) { 
         foreach($node->childNodes as $detail){ 
          if($detail->nodeType==XML_ELEMENT_NODE) { 

           /* add values from details */ 
           $row[ $detail->tagName ]=$detail->nodeValue; 

           /* add column headers/tagnames for nodes within details */ 
           $cols[]=$detail->tagName; 
          } 
         } 
        } else { 
         $cols[]=$node->tagName; 
         $row[ $node->tagName ]=$node->nodeValue; 
        } 
       } 
      } 
      fputcsv($handle, $row); 
     } 
    } 
} 

/* change handle to the final output file & truncate before writing */ 
$handle=fopen($output, 'w+'); 

/* add column headers */ 
fputcsv($handle, $cols); 

/* close file handle */ 
@fclose($handle); 

/* copy contents of temp file to output */ 
file_put_contents($output, file_get_contents($tmp), FILE_APPEND); 

/* delete temp file */ 
@unlink($tmp); 


$dom=$col=$person=$node=$handle=null; 
+0

Les données que j'ai considérées font partie de très grandes données. Je dois donc le considérer comme un fichier séparé. – KSK

+0

Ce n'est pas un problème, vous pouvez charger un fichier XML facilement - voir les changements ci-dessus – RamRaider

+0

Si les données en XML changent dynamiquement, cela ne fonctionne pas correctement car chaque fois que nous ne pouvons pas charger le fichier XML manuellement. – KSK