How can I encode xml files to xfdl (base64-gzip)?
As far as I know you cannot find the compression level of an already compressed file. When you are compressing the file you can specify the compression level with -# where the # is from 1 to 9 (1 being the fastest compression and 9 being the most compressed file). In practice you should never compare a compressed file with one that has been extracted and recompressed, slight variations can easily crop up. In your case I would compare the base64 encoded versions instead of the gzip'd versions.
Check these out:
http://www.ourada.org/blog/archives/375
http://www.ourada.org/blog/archives/390
They are in Python, not Ruby, but that should get you pretty close.
And the algorithm is actually for files with header 'application/x-xfdl;content-encoding="asc-gzip"' rather than 'application/vnd.xfdl; content-encoding="base64-gzip"'But the good news is that PureEdge (aka IBM Lotus Forms) will open that format with no problem.
Then to top it off, here's a base64-gzip decode (in Python) so you can make the full round-trip:
with open(filename, 'r') as f: header = f.readline() if header == 'application/vnd.xfdl; content-encoding="base64-gzip"\n': decoded = b'' for line in f: decoded += base64.b64decode(line.encode("ISO-8859-1")) xml = zlib.decompress(decoded, zlib.MAX_WBITS + 16)
I did this in Java with the help of the Base64 class from http://iharder.net/base64.
I've been working on an application to do form manipulation in Java. I decode the file, create an DOM document from the XML then write it back to file.
My code in Java to read the file looks like this:
public XFDLDocument(String inputFile) throws IOException, ParserConfigurationException, SAXException{ fileLocation = inputFile; try{ //create file object File f = new File(inputFile); if(!f.exists()) { throw new IOException("Specified File could not be found!"); } //open file stream from file FileInputStream fis = new FileInputStream(inputFile); //Skip past the MIME header fis.skip(FILE_HEADER_BLOCK.length()); //Decompress from base 64 Base64.InputStream bis = new Base64.InputStream(fis, Base64.DECODE); //UnZIP the resulting stream GZIPInputStream gis = new GZIPInputStream(bis); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); doc = db.parse(gis); gis.close(); bis.close(); fis.close(); } catch (ParserConfigurationException pce) { throw new ParserConfigurationException("Error parsing XFDL from file."); } catch (SAXException saxe) { throw new SAXException("Error parsing XFDL into XML Document."); }}
My code in java looks like this to write the file to disk:
/** * Saves the current document to the specified location * @param destination Desired destination for the file. * @param asXML True if output needs should be as un-encoded XML not Base64/GZIP * @throws IOException File cannot be created at specified location * @throws TransformerConfigurationExample * @throws TransformerException */ public void saveFile(String destination, boolean asXML) throws IOException, TransformerConfigurationException, TransformerException { BufferedWriter bf = new BufferedWriter(new FileWriter(destination)); bf.write(FILE_HEADER_BLOCK); bf.newLine(); bf.flush(); bf.close(); OutputStream outStream; if(!asXML) { outStream = new GZIPOutputStream( new Base64.OutputStream( new FileOutputStream(destination, true))); } else { outStream = new FileOutputStream(destination, true); } Transformer t = TransformerFactory.newInstance().newTransformer(); t.transform(new DOMSource(doc), new StreamResult(outStream)); outStream.flush(); outStream.close(); }
Hope that helps.