简体   繁体   中英

Symfony convert XLIFF files to another format (e.g. JSON or CSV)

I am using XLIFF files to handle Symfony 5.4 translations but my client would like to convert them to CSV or JSON.

Is it possible to convert my existing files to another format? I don't want to use the extract or update command because this would re-generate the translations. I would prefer to convert my existing ones in another format.

I also tried external tools such as xliff-to-json but they didn't work.

Since I couldn't find a suitable tool I created a console command which converts from XLIFF to CSV:

This is the link to the Gist, please feel free to suggest edits: https://gist.github.com/lukepass/6955d0cf25c44138df24f605e53a96cb

<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\Loader\XliffFileLoader;

#[AsCommand(
    name: 'app:convert-translations',
    description: 'Converts translation files from XLIFF to CSV.'
)]
class ConvertTranslationsCommand extends Command
{
    private string $projectDir;

    public function __construct(string $projectDir)
    {
        // best practices recommend to call the parent constructor first and
        // then set your own properties. That wouldn't work in this case
        // because configure() needs the properties set in this constructor
        $this->projectDir = $projectDir;

        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('locale', InputArgument::REQUIRED, 'Locale')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        /** @var string $locale */
        $locale = $input->getArgument('locale');

        $translationsDir = $this->projectDir.DIRECTORY_SEPARATOR.'translations';

        // takes all the XLIFF files in the translations directory using the Finder component
        $finder = new Finder();
        $finder->files()->in($translationsDir)->name('*.'.$locale.'.xlf');

        if (!$finder->hasResults()) {
            $io->error('No XLIFF files found in the translations directory.');

            return Command::FAILURE;
        }

        // iterates over all the XLIFF files found and converts them to CSV
        foreach ($finder as $file) {
            $xliffFileLoader = new XliffFileLoader();
            $messageCatalogue = $xliffFileLoader->load($file->getRealPath(), $locale);
            $translations = [];

            foreach ($messageCatalogue->all('messages') as $id => $translation) {
                $translations[$id] = $translation;
            }

            // replaces the XLIFF file extension with '.csv'
            $csvFilePath = str_replace('.xlf', '.csv', $file->getRealPath());

            // creates the CSV file and adds the BOM (Byte Order Mark)
            // this is required to make LibreOffice being able to open it
            $csvFile = fopen($csvFilePath, 'w');

            // writes the actual CSV contents using ';' as the delimiter
            foreach ($translations as $id => $translation) {
                fputcsv($csvFile, [$id, $translation], ';');
            }

            fclose($csvFile);

            $io->success(sprintf('XLIFF file "%s" converted to CSV.', $file->getFilename()));
        }

        return Command::SUCCESS;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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