XFDL in Linux :: Part 1

Earlier, I wrote about using PureEdge Viewer, which is Windows software from IBM on Linux through Wine. This got me thinking, do we need to use Windows software. A quick look at the file and through Google and it’s easy to see that an *.xfdl file is a gzipped, base64 encoded xml file. So this is part one of what I hope to be a tutorial into designing software on Linux using python to open, read and write xfdl files in the same way as PureEdge Viewer. It gets annoying, to say the least, to need to open Windows in VirtualBox, or an actual install to read and edit *.xfdl files. The barriers I see at this preliminary point is to convert the xml to a readable image and then to make that editable where possible.

So, in this first part, we will do the very basic converting an *.xfdl file to an *.xml file. The code should be self explanatory but if there are questions, post them through comments and I’ll do my best at getting an answer to you.

#!/usr/bin/python
""" IMPORTS """
from base64 import *
import gzip, os, sys

""" DEATH!!! """
# Standard way to die...
def die(msg=None):
    if msg == None:
        msg = "Unknown error."
    print " [*] ERROR - %s" % msg
    sys.exit(1)

""" CHECK FOR FILE """
# No file name, then we have nothing to do!
if len(sys.argv) < 2:
    die("Did not specifiy a file name.")

""" GET FILE """
# In a more advanced version, this will check the magic value of the file as well to
# ensure it is an *.xfdl file.
filename = sys.argv[1]
print "Using %s" % filename

""" OPEN FILE AND SPLIT """
# Nothing tough, grab the magic number (1st line) and then store the rest as a variable.
f = open(filename,'r').read()
magic = f.splitlines()[0]
print "magic: %s" % magic
data = f.split(magic)[1]
print "Got Data."
del f

""" BASE64 DECODE """
# First we decode the base64.
f = open('temp.gz','wb')
f.write(b64decode(data))
f.close()
print "Base64 Decoded."

""" GUNZIP DATA """
# Yes, I know this writing to a file and then deleting it is ugly but I have not found
# a way to gunzip from a data stream.
f = gzip.open('temp.gz','rb')
gunzip_data = f.read()
f.close()
os.remove('temp.gz')
print "Gunzipped Data."

""" SAVE XML FILE """
# As this gets more advanced, it should be able to stay as a data stream for editing.
filename = filename.split(".")[0] + ".xml"
f = open(filename,'wb')
f.write(gunzip_data)
f.close()
print "Saved to temporary file '%s'" % filename

Nothing too involved here, simply open the file, strip out the first line and the decode the rest from base64 and gunzip that data to get the xml inside. ┬áIn the next tutorial, we’ll look at the structure of that xml, once I actually understand it or find decent documentation on it!

2 thoughts on “XFDL in Linux :: Part 1”

  1. “Yes, I know this writing to a file and then deleting it is ugly but I have not found a way to gunzip from a data stream.”

    — Use the io module (formerly known as StringIO/cStringIO in python2)

    Though I hope over a year later you would have figured that out.

    For whatever reason I couldn’t make the zlib module work, although that’s supposed to be what you would use.

    I found the last paragraph much more useful than your code–that was one useful sentence, thank you.

    Here’s how I would write that:

    http://sprunge.us/bFJD?python

    (remove the query string to view the raw file)

    I’m interested in parsing and rendering the resulting XML; do you have any other python to share?

    1. Yes, IO works just fine and I did find it shortly after this post. For doing this on Windows with VBA to use in MS Office, I developed first an executable that’d do this and then a DLL that I can import to VBA. This code could be something that could be easily ported to a C/Python module so that may be a next project. Thanks for your code example, it was very clean and efficient!

Leave a Reply

Your email address will not be published. Required fields are marked *