Embedding binary data into an REXML doc?

G

gregarican

I am creating an inventory export script using Ruby. The inventory data
is being exported to an XML document using REXML. Each inventory item
has an associated JPG image stored in the database and I want to attach
it to each item in the XML doc. For a test I am just writing out the
file name. I was wondering if it is possible to encode the binary data
and attach that to the item.

Anyone have suggestions?
 
R

Ross Bamford

I am creating an inventory export script using Ruby. The inventory data
is being exported to an XML document using REXML. Each inventory item
has an associated JPG image stored in the database and I want to attach
it to each item in the XML doc. For a test I am just writing out the
file name. I was wondering if it is possible to encode the binary data
and attach that to the item.

Anyone have suggestions?

How about just using base64, e.g. (not REXML, but should convert right
across):

=========================
require 'xml/libxml'
require 'base64'

xp = XML::parser.string <<EOX
<?xml version='1.0'?>
<image>
<type>image/gif</type>
<data><![CDATA[#{Base64.encode64(File.read('img1.gif'))}]]></data>
</image>
EOX

xd = xp.parse
p xd

xd.find('/image/data').each { |n| p Base64.decode64(n.content) }
__END__

=========================
##### OUTPUT:

<?xml version="1.0"?>
<image>
<type>image/gif</type>
<data><![CDATA[R0lGO ...
... AOw==
]]></data>
</image>

"GIF89a\026\000 ... "
=========================

There are more complex ways involving the mime/related content type, but
for that you'll probably need extra equipment to handle the MIME data. See:

http://www.xml.com/pub/a/98/07/binary/binary.html
 
G

gregarican

Ross said:
How about just using base64, e.g. (not REXML, but should convert right
across):

That worked perfectly. Thanks so much, as this ties things up quite
nicely!

*sigh of relief*
 
G

gregarican

gregarican wrote:

That worked perfectly. Thanks so much, as this ties things up quite
nicely!

*sigh of relief*


There is one thing I noticed. I hadn't worked with Ruby Base64 before
and when I tried to encode graphic files averaging 20-30 KB only the
first 60 characters were encoded. Reading the Base64 API I saw there
was a parameter specifying the length of encoded data. But tweaking
things I still couldn't get Ruby Base64 to encode the entirety of a
graphic file. So I piped in a Python Base64 encoding of the graphic
file with the filename passed in as a command line parameter instead.
Clunky for sure. Am I missing something very basic that would stop Ruby
Base64 from encoding an entire graphic file?
 
R

Ross Bamford

There is one thing I noticed. I hadn't worked with Ruby Base64 before
and when I tried to encode graphic files averaging 20-30 KB only the
first 60 characters were encoded. Reading the Base64 API I saw there
was a parameter specifying the length of encoded data. But tweaking
things I still couldn't get Ruby Base64 to encode the entirety of a
graphic file. So I piped in a Python Base64 encoding of the graphic
file with the filename passed in as a command line parameter instead.
Clunky for sure. Am I missing something very basic that would stop Ruby
Base64 from encoding an entire graphic file?

I'm guessing here, but are you on Windows? If so, you'll probably need to
swap out:

Base64.encode64(File.read('img1.gif'))

for something like:

Base64.encode64(File.open('img1.gif','rb') { |f| f.read })

It's probably best practice to always do this (other platforms just ignore
it) so I should have put that in the example.

(Aside: I think the parameter you noticed controls the length of the
output lines, rather than the actual data length. It shouldn't make any
difference here AFAIK.)

Hope that helps,
 
G

gregarican

Ross said:
I'm guessing here, but are you on Windows? If so, you'll probably need to
swap out:

Base64.encode64(File.read('img1.gif'))


for something like:


Base64.encode64(File.open('img1.gif','rb') { |f| f.read })


It's probably best practice to always do this (other platforms just ignore
it) so I should have put that in the example.

That worked perfectly, and your assumption of my Windows platform was
spot on. Thanks for the help!
 
D

Dave Burt

gregarican said:
That worked perfectly, and your assumption of my Windows platform was
spot on. Thanks for the help!

The issue is that without "b" file open mode option, only on Windows,
"\r\n" gets conflated to "\n".

I wonder when we'll get File.binread to do this.

Cheers,
Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

REXML Speed Question 3
Update existing doc with REXML 1
REXML Input File Question 7
REXML advice - output 7
REXML 19
Errors on REXML reading an HTML. 1
REXML raw all doesn't seem to work 0
Question about REXML 2

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top