简体   繁体   English

使用PHP将CSV转换为XML

[英]Convert CSV to XML using PHP

I have multiple CSV files in a folder with different data. 我在具有不同数据的文件夹中有多个CSV文件。 I want to read in 1 CSV file at a time, convert the data to XML and then output the file as .xml before reading in the next CSV file. 我想一次读取一个CSV文件,将数据转换为XML,然后将文件输出为.xml,然后再读取下一个CSV文件。

Currently, the CSV files that I have all have a header row in it. 目前,我所有的CSV文件中都有标题行。 The code I ave right now runs fine for all the CSV files that have a header row in it. 我现在使用的代码对于所有带有标题行的CSV文件都可以正常运行。

However, when it reads in a file that does not have a header row in it, it throws an error. 但是,当它读取其中没有标题行的文件时,将引发错误。 I want it to be able to detect if there is no headings in the header row and then make it input strings which have been preset in variables in the code. 我希望它能够检测标题行中是否没有标题,然后使其输入已在代码中的变量中预设的字符串。 Is this possible? 这可能吗?

Current Code 当前代码

function converttoxml( $input_filename ) {

echo $input_filename;

//set the delimiter
$delimiter = "," ;

//set count to 0
$row_count++ ;

//strip the input filename of the extension
$stripped = pathinfo($input_filename, PATHINFO_FILENAME);

//set output filename
$outputFilename  = UPLOAD_DIR."/".$stripped.".xml";

//open inputfilename
$inputFile  = fopen( $input_filename, 'rt' );

//get input file pointers for csv parsing
$headers = fgetcsv( $inputFile );

//create new DOM document
$doc  = new DomDocument();

//set the output to clean
$doc->formatOutput = true;

//create element
$root = $doc->createElement( 'Shipping_Details' );

$root = $doc->appendChild( $root );

//while there are rows in the csv file
while ( ( $row = fgetcsv( $inputFile ) ) !== FALSE ) {

    //create container row
    $container = $doc->createElement('Job_Header_Details');

        //for loop
        foreach ( $headers as $i => $header ) {

            //explode with the delimiter the header
            $arr = explode( $delimiter, $header );

            //print_r($arr);

                //for loop
                foreach ( $arr as $key => $ar ) {

                    //only accept regualar expressions matching this
                    $child = $doc->createElement(preg_replace( "/[^A-Za-z0-9]/","",$ar ) );

                    //add the previous child to $child
                    $child = $container->appendChild( $child );

                    //explode row with delimiter
                    $whole = explode( $delimiter, $row[$i] );

                    //left and right trim anything with speechmarks
                    $value = $doc->createTextNode( ltrim( rtrim( $whole[$key], '"') ,'"') );

                    //append previous value to $value
                    $value = $child->appendChild( $value );

                }//for
        }//for

   //append to root - container
   $root->appendChild($container);

}//while



echo "Saving the XML file\n" ;

$result = $doc->saveXML();

echo "Writing to the XML file\n" ;

$handle = fopen( $outputFilename, "w" );

fwrite( $handle, $result );

fclose( $handle );

return $outputFilename;

Examples of CSV files that will/willnot process 将会/不会处理的CSV文件示例

CSV File example that will work with above code 可以使用上述代码的CSV文件示例

CSV File example that will NOT work with the above code CSV文件例如不会与上面的代码工作

With the example that will not work, I believe it is because the header row is missing. 对于该示例将不起作用的情况,我相信是因为缺少标题行。 In this case, I want to somehow define what each column heading should be and input it in. 在这种情况下,我想以某种方式定义每个列标题应输入的内容。

for example 例如

$column_1 = "<heading1>";
$column_2 = "<heading2>";
$column_3 = "<heading3>";
$column_4 = "<heading4>";
$column_5 = "<heading5>";
$column_6 = "<heading6>";

etc.. 等等..

So when the script runs and it detects headings in the CSV file, it will use them. 因此,当脚本运行并检测到CSV文件中的标题时,它将使用它们。 But when it detects that they are not there, the it will use the above $column examples to input the in. 但是,当检测到它们不存在时,它将使用上面的$ column示例输入in。

The error I get when a CSV file does not have a header description CSV文件没有标题说明时出现的错误

缺少标题错误

Any ideas? 有任何想法吗?

Just to try this out, added ... 只是为了尝试一下,添加...

    //get input file pointers for csv parsing
    $headers = fgetcsv( $inputFile );

    $row = 1;
    foreach ( $headers as &$header )   {
        if (preg_match('/\A(?!XML)[a-z][\w0-9-]*/i', $header) === 0 ) {
           $header = 'heading'.$row;
        }
        $row++;
    }
    unset($header);

Which when passed in a header of a,1223 produces headers of a,heading2 . 当传入a,1223标头时会生成a,heading2标头。 Whereas a,b gives a,b . a,b给出a,b

Update: Although if any element fails, you'll want to process this row as data by the look of it. 更新:尽管任何元素失败,但您还是希望通过外观将其作为数据进行处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM