phpxmlcsvfgetsfgetcsv

PHP script creates XML files from CSV's but holds 0 contents


I have created a php script to read through 19 csv files and normalises the data - not holding repeating data (station id, name & geocode) and only holding the attributes for each record which have values. I have printed the csv's to make sure the are loading within the script and the script also makes the data-site-id files but contains 0 contents within the file?


<?php

ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

// List of CSV files
$csvFiles = [
    'data-203.csv',
    'data-206.csv',
    'data-209.csv',
    'data-270.csv',
    'data-213.csv',
    'data-215.csv',
    'data-271.csv',
    'data-375.csv',
    'data-395.csv',
    'data-447.csv',
    'data-452.csv',
    'data-463.csv',
    'data-500.csv',
    'data-501.csv',
    'data-672.csv',
    'data-188.csv',
    'data-209.csv',
    'data-481.csv',
    'data-228.csv',
    'data-459.csv',

];

// Loop through each CSV file
foreach ($csvFiles as $csvFile) {
    $csvFilePath = __DIR__ . '/' . $csvFile;
    
    // Open the CSV file
    if (($handle = fopen($csvFilePath, 'r')) !== false) {
        // Create an XMLWriter instance
        $xmlWriter = new XMLWriter();
        $xmlWriter->openURI(csvFileToXmlFile($csvFile));
        $xmlWriter->startDocument('1.0', 'UTF-8');
        $xmlWriter->startElement('data');

        // Read the CSV file line by line
        while (($data = fgetcsv($handle)) !== false) {
            // Skip empty lines
            if (count($data) === 0) {
                continue;
            }

            // Ensure the array has the necessary indexes
            if (count($data) >= 4) {
                // Extract the necessary data
                $stationId = $data[0];
                $name = $data[1];
                $geocode = $data[2];
                $attribute = $data[3];

                // Check if the attribute has a value
                if (trim($attribute) !== '') {
                    // Start XML record element
                    $xmlWriter->startElement('record');
                    $xmlWriter->writeAttribute('station_id', $stationId);
                    $xmlWriter->writeAttribute('name', $name);
                    $xmlWriter->writeAttribute('geocode', $geocode);
                    $xmlWriter->writeAttribute('attribute', $attribute);
                    // End XML record element
                    $xmlWriter->endElement();
                }
            }
        }

        // Close XML elements and file
        $xmlWriter->endElement();
        $xmlWriter->endDocument();
        $xmlWriter->flush();
        fclose($handle);

        // Output success message
        $xmlFile = csvFileToXmlFile($csvFile);
        echo "XML file generated successfully: $xmlFile\n";
    }
}

// Function to convert CSV file name to XML file name
function csvFileToXmlFile($csvFile) {
    $fileParts = pathinfo($csvFile);
    $xmlFile = $fileParts['filename'] . '.xml';
    return $xmlFile;
}

?>

As mentioned, I have printed the csv's to make sure they are being read within the directory. I also changed the $xmlWriter->openURI($csvFileToXmlFile($csvFile)); to $xmlWriter->openURI(csvFileToXmlFile($csvFile));. I have been getting Undefined offset 2 & 3. Line 52 & 53 error before hand too, these have subsided.

Sample image of csv, wasn't sure how to send it https://drive.google.com/file/d/1EUHN4RCJFq-XrIBQNvZphh7vxZDdbf_R/view?usp=share_link

Blank XML - data-481.xml https://drive.google.com/file/d/1pEinOeosPQQRoeQoJHfEb6L_80iD5bqr/view?usp=share_link

desired XML


Solution

  • You must learn to look closely at your data. The csv files are in fact ssv files "SemiColon seperated value" files

    All you need to do is change this line of code to let fgetcsv() know the seperator is a ;

        while (($data = fgetcsv($handle,10000,';')) !== false) {
    

    Second Issue with data-481.csv

    the $data[1], $data[2], $data[3] columns are all empty for all lines

    So

    $attribute = $data[3];
    if (trim($attribute) !== '') {
    

    which controls whether the row gets written to the xml file fails, so no data is written