Using tidy is very simple to fix a broken ods/odt document
I wrote the following code to be run from command line
<?php
$zip = new ZipArchive();
if ($zip->open($argv[1])) {
$fp = $zip->getStream('content.xml'); if(!$fp)
die("Error: can't get stream to document file");
$stat = $zip->statName('content.xml');
$buf = ""; ob_start(); while (!feof($fp)) {
$buf .= fread($fp, 2048);
}
$s = ob_get_contents();
ob_end_clean();
fclose($fp);
$zip->close();
$config = array(
'indent' => true,
'clean' => true,
'input-xml' => true,
'output-xml' => true,
'wrap' => false
);
$tidy = new Tidy();
$xml = $tidy->repairstring($buf, $config);
$array=split("\n",$xml);
$file=tempnam("/tmp","xml");
$fp=fopen($file,"rw+");
foreach ($array as $key=>$value) {
fwrite($fp,trim($value),strlen(trim($value)));
if ($key==0) {
fwrite($fp,"\n");
}
}
fclose($fp);
if ($zip->open($argv[1]) === TRUE) {
$zip->deleteName('content.xml');
$zip->addFile($file, 'content.xml');
$zip->close();
echo 'recovery complete';
} else {
echo 'recovery failed';
}
unlink($file);
}
?>
save it to a file called fixdoc and invoke as:
php fixdoc yourbrokendoc
for your safety, please work on a copy of your doc.