Exemple #1
0
function read_csv($out, $in_file, $options = array())
{
    if (!isset($options["enclosure"])) {
        $options["enclosure"] = '"';
    }
    $enclosure = $options["enclosure"];
    $delimiter = $options["delimiter"];
    // CSVファイルを正規化する。
    $tmp = tmpfile();
    if (($in = fopen($in_file, "r")) === false) {
        fputs(STDERR, "Error[{$in_file}]: Failed to open the file.\n");
        return;
    }
    while (($line = fgets($in)) !== false) {
        // UTF-8にする。
        $line = normalize_encoding($line);
        // 全角カタカナ、半角英数字、PHP_EOL、NFCにする。
        $line = normalize_string($line);
        fputs($tmp, $line);
    }
    fclose($in);
    fflush($tmp);
    rewind($tmp);
    // ワークシートの先頭行に "# ファイル名" を出力する。
    $filename = pathinfo($in_file, PATHINFO_FILENAME);
    $ext = pathinfo($in_file, PATHINFO_EXTENSION);
    $filename_fragments = explode(".", $filename);
    $worksheet_name = $filename_fragments[count($filename_fragments) - 1];
    fputs($out, "# {$worksheet_name}\n");
    $headers = explode(":", "^:" . $options["inheader"] . ":\$");
    while (($csv_record = fgetcsv($tmp, 65536, $delimiter, $enclosure)) !== FALSE) {
        for ($i = 0; $i < count($csv_record); $i++) {
            $csv_record[$i] = trim($csv_record[$i]);
        }
        if (($header = array_shift($headers)) !== null) {
            if ($header == "^") {
                $num_cols = count($csv_record);
                $fields = array_fill(0, $num_cols, "");
                $types = array_fill(0, $num_cols, "text");
                $params = array_fill(0, $num_cols, "");
                $titles = array_fill(0, $num_cols, "");
                $header = array_shift($headers);
            }
            if ($header == "F") {
                $fields = array_replace($fields, $csv_record);
            } else {
                if ($header == "C") {
                    $types = array_replace($types, $csv_record);
                } else {
                    if ($header == "P") {
                        $params = array_replace($params, $csv_record);
                    } else {
                        if ($header == "T") {
                            $titles = array_replace($titles, $csv_record);
                        } else {
                            if ($header == "N") {
                            } else {
                                if ($header == "\$") {
                                    for ($i = 0; $i < count($fields); $i++) {
                                        if ($fields[$i] == "") {
                                            $fields[$i] = $titles[$i];
                                        }
                                        if ($fields[$i] == "") {
                                            $fields[$i] = "f{$i}";
                                            $titles[$i] = "f{$i}";
                                        }
                                    }
                                    array_unshift($fields, "fields");
                                    fputcsv($out, $fields, ",", '"');
                                    array_unshift($types, "types");
                                    fputcsv($out, $types, ",", '"');
                                    array_unshift($params, "params");
                                    fputcsv($out, $params, ",", '"');
                                    array_unshift($titles, "titles");
                                    fputcsv($out, $titles, ",", '"');
                                    $headers = array();
                                    // (最初の)データを出力する。
                                    array_unshift($csv_record, "record");
                                    fputcsv($out, $csv_record, ",", '"');
                                }
                            }
                        }
                    }
                }
            }
        } else {
            // データを出力する。
            array_unshift($csv_record, "record");
            fputcsv($out, $csv_record, ",", '"');
        }
    }
    // ワークシートの最終行に空行を出力する。
    fputs($out, "\n");
    fclose($tmp);
    return;
}
function read_yaml($out, $in_file, $options = array())
{
    // YAMLオブジェクトを読む。
    $contents = file_get_contents($in_file);
    $contents = normalize_encoding($contents);
    $contents = normalize_string($contents);
    // parse yaml, '0' for the first document
    if (($dataset = yaml_parse($contents, 0)) === FALSE) {
        fputs(STDERR, "Error[{$in_file}]: The file is not valid format.\n");
        return;
    }
    if (!is_array($dataset)) {
        fputs(STDERR, "Error[{$in_file}]: The 1st level is not an object.\n");
    }
    foreach ($dataset as $worksheet_name => $worksheet) {
        if (!is_array($worksheet)) {
            fputs(STDERR, "Error[{$in_file}]: The 2nd level is not an array.\n");
            return;
        }
        // Pass1: ヘッダとフィールド名を収集する。
        $fields = array();
        $titles = array();
        $types = array();
        $params = array();
        $records = array();
        $num_cols = 0;
        if ($worksheet["titles"] !== null) {
            $titles = array_values($worksheet["titles"]);
            $fields += array_keys($worksheet["titles"]);
        }
        if ($worksheet["types"] !== null) {
            $types = array_values($worksheet["types"]);
            $fields += array_keys($worksheet["types"]);
        }
        if ($worksheet["params"] !== null) {
            $params = array_values($worksheet["params"]);
            $fields += array_keys($worksheet["params"]);
        }
        if ($worksheet["records"] !== null) {
            $records = array_values($worksheet["records"]);
            for ($row = 0; $row < count($records); $row++) {
                $fields += array_keys($records[$row]);
            }
        }
        if (($num_cols = count($fields)) == 0) {
            fputs(STDERR, "Error[{$in_file}]: No field specidied.\n");
            return;
        }
        // Pass2: 内部形式CSVを出力する。
        // 先頭行に "# ファイル名" を出力する。
        fputs($out, "# {$worksheet_name}\n");
        // ヘッダ行を出力する。
        $fields = array_pad($fields, $num_cols, "");
        array_unshift($fields, "fields");
        fputcsv($out, $fields, ",", '"');
        $types = array_pad($types, $num_cols, "text");
        array_unshift($types, "types");
        fputcsv($out, $types, ",", '"');
        $params = array_pad($params, $num_cols, "");
        array_unshift($params, "params");
        fputcsv($out, $params, ",", '"');
        $titles = array_pad($titles, $num_cols, "");
        array_unshift($titles, "titles");
        fputcsv($out, $titles, ",", '"');
        // データ行を出力する。
        for ($row = 0; $row < count($records); $row++) {
            $record = $records[$row];
            $csv_record = array();
            // $fields は上で unshift しているので 1 から開始する。
            for ($col = 1; $col < count($fields); $col++) {
                $csv_record[$col] = $record[$fields[$col]];
            }
            array_unshift($csv_record, "record");
            fputcsv($out, $csv_record, ",", '"');
        }
        // 最終行に空行を出力する。
        fputs($out, "\n");
    }
    return;
}
Exemple #3
0
function read_xml($out, $in_file, $options = array())
{
    // XMLオブジェクトを読む。
    $contents = normalize_encoding(file_get_contents($in_file));
    $contents = normalize_string($contents);
    $dom = new DOMDocument("1.0", "UTF-8");
    $dom->loadXML($contents);
    // 第1レベル要素(ルート)を取得する。固定名(dataset)でなくても受理する。
    $node1 = $dom->documentElement;
    for ($i = 0; $i < $node1->childNodes->length; $i++) {
        // 第2レベル要素(ワークシート)を取得する。
        $node2 = $node1->childNodes->item($i);
        if (!$node2 instanceof DOMElement) {
            continue;
        }
        // タグ間の改行は無視する。
        $worksheet_name = (string) $node2->tagName;
        // Pass1: ヘッダとフィールド名を収集する。
        $titles = array();
        $types = array();
        $params = array();
        $records = array();
        for ($j = 0; $j < $node2->childNodes->length; $j++) {
            // 第3レベル要素(オブジェクト)を取得する。
            $node3 = $node2->childNodes->item($j);
            if (!$node3 instanceof DOMElement) {
                continue;
            }
            // タグ間の改行は無視する。
            $object_name = (string) $node3->tagName;
            switch ($object_name) {
                case "titles":
                    for ($k = 0; $k < $node3->childNodes->length; $k++) {
                        // 第4レベル要素(フィールド)を取得する。
                        $node4 = $node3->childNodes->item($k);
                        if (!$node4 instanceof DOMElement) {
                            continue;
                        }
                        // タグ間の改行は無視する。
                        $field = (string) $node4->tagName;
                        $value = (string) $node4->nodeValue;
                        $titles[$field] = $value;
                    }
                    break;
                case "types":
                    for ($k = 0; $k < $node3->childNodes->length; $k++) {
                        // 第4レベル要素(フィールド)を取得する。
                        $node4 = $node3->childNodes->item($k);
                        if (!$node4 instanceof DOMElement) {
                            continue;
                        }
                        // タグ間の改行は無視する。
                        $field = (string) $node4->tagName;
                        $value = (string) $node4->nodeValue;
                        $types[$field] = $value;
                    }
                    break;
                case "params":
                    for ($k = 0; $k < $node3->childNodes->length; $k++) {
                        // 第4レベル要素(フィールド)を取得する。
                        $node4 = $node3->childNodes->item($k);
                        if (!$node4 instanceof DOMElement) {
                            continue;
                        }
                        // タグ間の改行は無視する。
                        $field = (string) $node4->tagName;
                        $value = (string) $node4->nodeValue;
                        $params[$field] = $value;
                    }
                    break;
                case "records":
                    for ($k = 0; $k < $node3->childNodes->length; $k++) {
                        // 第4レベル要素(レコード)を取得する。
                        $node4 = $node3->childNodes->item($k);
                        if (!$node4 instanceof DOMElement) {
                            continue;
                        }
                        // タグ間の改行は無視する。
                        $record = array();
                        for ($l = 0; $l < $node4->childNodes->length; $l++) {
                            // 第5レベル要素(フィールド)を取得する。
                            $node5 = $node4->childNodes->item($l);
                            if (!$node5 instanceof DOMElement) {
                                continue;
                            }
                            // タグ間の改行は無視する。
                            $field = (string) $node5->tagName;
                            $value = (string) $node5->nodeValue;
                            $record[$field] = $value;
                        }
                        $records[] = $record;
                        // $k はインデックスに使わないこと。
                    }
                    break;
            }
        }
        $fields = array();
        $num_cols = 0;
        $fields += array_keys($titles);
        $fields += array_keys($types);
        $fields += array_keys($params);
        for ($row = 0; $row < count($records); $row++) {
            $fields += array_keys($records[$row]);
        }
        if (($num_cols = count($fields)) == 0) {
            fputs(STDERR, "Error[{$in_file}]: no field specidied.\n");
            return;
        }
        // Pass2: 内部形式CSVを出力する。
        // 先頭行に "# ファイル名" を出力する。
        fputs($out, "# {$worksheet_name}\n");
        // ヘッダ行を出力する。
        $fields = array_pad($fields, $num_cols, "");
        array_unshift($fields, "fields");
        fputcsv($out, $fields, ",", '"');
        $types = array_pad($types, $num_cols, "text");
        array_unshift($types, "types");
        fputcsv($out, $types, ",", '"');
        $params = array_pad($params, $num_cols, "");
        array_unshift($params, "params");
        fputcsv($out, $params, ",", '"');
        $titles = array_pad($titles, $num_cols, "");
        array_unshift($titles, "titles");
        fputcsv($out, $titles, ",", '"');
        // データ行を出力する。
        for ($row = 0; $row < count($records); $row++) {
            $record = $records[$row];
            $csv_record = array();
            // $fields は上で unshift しているので 1 から開始する。
            for ($col = 1; $col < count($fields); $col++) {
                $csv_record[$col] = $record[$fields[$col]];
            }
            array_unshift($csv_record, "record");
            fputcsv($out, $csv_record, ",", '"');
        }
        // 最終行に空行を出力する。
        fputs($out, "\n");
    }
    return;
}