Mengekstraksi data dari database Postgres ke XML melalui Perl - masalah penyandian

Saya memiliki database Postgres yang dikodekan dalam UTF-8. Saya menggunakan Perl dengan modul berikut:

use DBI
use XML::Generator::DBI
use XML::SAX::Writer

untuk mengekstrak data dalam database Postgres ke file XML menggunakan query, yaitu:

use DBI;
use XML::Generator::DBI;
use XML::SAX::Writer;

my $dbh = DBI->connect("dbi:Pg:dbname=postgres;host=MYHOST;port=2278",
                      username,
                      password,
                      {RaiseError => 1},
                     );

my $handler = XML::SAX::Writer->new( Output => 'foo.xml' );

my $generator = XML::Generator::DBI->new(
 Handler => $handler,
 dbh     => $dbh,
 Indent  => 1,
);

$select = qq(

!!!!SQL QUERY!!!!!

);

$generator->execute(
                     $select, 
                     undef,
                     RootElement => 'root',
                        );

Ini berfungsi dengan baik dan saya mendapatkan dokumen XML yang valid sebagai hasilnya. Masalah saya adalah beberapa data dalam database adalah biner - yaitu ada karakter non UTF-8 di sana. Ketika ini terjadi, XML::Generator::DBI mendeteksi ini dan mengeluarkan data sebagai berikut dalam file XML:

<foo dbi:encoding='base64'>VGhpcyByZXBvcnQgbGlzdHMgYWxsIGZpbGVzIGhhdmluZyBhY2Nlc3NlcyB0byBkYXRhYmFzZSB0
YWJsZXMuDQpJdCBwcm92aWRlcyB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uOiAgRmlsZSBmdWxs
IG5hbWUsIGFjY2Vzc2VkIHRhYmxl
</foo>

Namespace juga terikat pada URL http://axkit.org/NS/xml-generator-dbi. Ini adalah perilaku yang benar menurut dokumentasi modul, tetapi yang ingin saya ketahui adalah: apakah mungkin mengubah string yang disandikan base64 ini menjadi UTF-8 sehingga saya benar-benar dapat menggunakannya?

Saya sama sekali bukan ahli Perl, atau Postgres, jadi santai saja! terimakasih banyak.


person JamesH    schedule 09.12.2010    source sumber


Jawaban (2)


Saya membayangkan Anda dapat memecahkan kode Base64 menggunakan MIME::Base64 ... Tapi itu tergantung datanya. Jika ada karakter non-UTF-8, apakah itu? Anda perlu tahu dari apa harus diubah.

person FalseVinylShrub    schedule 09.12.2010
comment
Terima kasih untuk balasan Anda. Tidak tahu tentang modul ini - terima kasih (belum yakin bagaimana cara mengintegrasikannya tetapi akan memeriksanya). Data yang keluar sebagai base64 biasanya berupa sampel kode, misalnya sampel pengkodean Java, C++ yang telah disimpan dalam tabel - tetapi belum tentu demikian. Sebagai contoh dalam pertanyaan saya, ini diterjemahkan menjadi: Laporan ini mencantumkan semua file yang memiliki akses ke tabel database. Ini memberikan informasi berikut: Nama lengkap file, tabel yang diakses - jadi saya kira itu pasti : yang menyebabkan keluaran base64? - person JamesH; 10.12.2010
comment
Hanya memperluas data sebenarnya. Contoh yang saya berikan dalam pertanyaan saya sebenarnya disimpan seperti ini di database Postgres: Laporan ini mencantumkan semua file yang memiliki akses ke tabel database. Ini memberikan informasi berikut: Nama lengkap file, tabel yang diakses I.e. Saya yakin ada kereta kembali ke sana setelah perhentian penuh pertama. Dalam contoh ini, inilah alasan mengapa base64 digunakan sebagai : adalah karakter yang diperbolehkan UTF-8 dan tidak boleh menyebabkan penggunaan base64... - person JamesH; 10.12.2010
comment
Selanjutnya... Saya mencari skrip yang membuat data ini. berikut isinya: Laporan ini mencantumkan semua file yang memiliki akses ke tabel database.!xD!``!xA!Ini memberikan informasi berikut: Nama lengkap file, tabel yang diakses - person JamesH; 10.12.2010
comment
Oke, saya tidak yakin mengapa ini menerjemahkannya ke Base64. Carriage return adalah karakter yang valid di UTF-8. Apakah Anda yakin XML::Generator::DBI adalah modul terbaik? Bagaimana kalau menggunakan DBI biasa dan XML::Generator biasa, dan melakukan sendiri bagian tengahnya? Saya tidak punya banyak waktu untuk membahas hal ini, tetapi jika Anda senang dengan langkah ini, teruslah berkomentar dan saya akan memperbarui jawabannya ketika saya mendapatkan ide yang lebih jelas ;-) - person FalseVinylShrub; 10.12.2010

Jika yang Anda maksud dengan "biner" adalah tipe kolom di PostgreSQL adalah bytea, maka Anda dapat:

  1. Setel bytea_output=escape pada $dbh, seperti ini:

    $dbh->do('SET bytea_output=escape');

  2. Transmisikan kolom dengan tipe bytea hingga text dalam kueri Anda:

    SELECT bytea_column::text FROM ...

Saya ragu salah satu dari keduanya akan menjadi hasil akhir yang Anda inginkan. Mudah-mudahan itu akan membawa Anda ke arah yang benar.

person Dave Gray    schedule 04.04.2014