Created
May 9, 2022 22:02
-
-
Save jmini/4acd5749543fb70b24242565f4edf6b9 to your computer and use it in GitHub Desktop.
Decode drawio compressed xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///usr/bin/env jbang "$0" "$@" ; exit $? | |
//DEPS com.github.vlsi.mxgraph:jgraphx:4.2.2 | |
//JAVA 8 | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.OutputStream; | |
import java.io.OutputStreamWriter; | |
import java.net.URLDecoder; | |
import java.nio.charset.StandardCharsets; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.util.Base64; | |
import java.util.zip.DataFormatException; | |
import java.util.zip.Inflater; | |
import javax.xml.transform.OutputKeys; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.TransformerException; | |
import javax.xml.transform.TransformerFactory; | |
import javax.xml.transform.dom.DOMSource; | |
import javax.xml.transform.stream.StreamResult; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Node; | |
import com.mxgraph.util.mxXmlUtils; | |
public class decodeDiagram { | |
public static void main(String... args) throws Exception { | |
if (args == null || args.length != 1) { | |
System.err.println("Usage: " + decodeDiagram.class.getSimpleName() + " <file path>"); | |
System.exit(1); | |
throw new IllegalStateException("Unreachable code"); | |
} | |
Path file = Paths.get(args[0]); | |
if (!Files.exists(file)) { | |
System.err.println("Can not read file: " + file); | |
System.exit(1); | |
throw new IllegalStateException("Unreachable code"); | |
} | |
String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8); | |
decodeDiagram instance = new decodeDiagram(); | |
Document document = instance.getDiagramData(content); | |
printDocument(document, System.out); | |
} | |
public Document getDiagramData(String xmlString) throws DataFormatException, IOException { | |
Document xmlDocument = mxXmlUtils.parseXml(xmlString); | |
Node diagram = xmlDocument.getElementsByTagName("diagram") | |
.item(0); | |
String textContent = diagram.getTextContent(); | |
if (!textContent.startsWith("<")) { | |
byte[] compressed = base64Decode(textContent); | |
byte[] decompressed = inflate(compressed); | |
textContent = urlDecode(new String(decompressed)); | |
Document expanded = mxXmlUtils.parseXml(textContent); | |
Node imported = xmlDocument.importNode(expanded.getFirstChild(), true); | |
diagram.setTextContent(null); | |
diagram.appendChild(imported); | |
} | |
return xmlDocument; | |
} | |
private byte[] inflate(byte[] compressed) throws IOException, DataFormatException { | |
int compressedDataLength = 0; | |
Inflater compresser = new Inflater(true); | |
compresser.setInput(compressed, 0, compressed.length); | |
ByteArrayOutputStream o = new ByteArrayOutputStream(compressed.length); | |
byte[] result = new byte[1024]; | |
try { | |
while (!compresser.finished()) { | |
compressedDataLength = compresser.inflate(result); | |
if (compressedDataLength == 0) { | |
break; | |
} | |
o.write(result, 0, compressedDataLength); | |
} | |
} finally { | |
o.close(); | |
} | |
compresser.end(); | |
return o.toByteArray(); | |
} | |
private byte[] base64Decode(String input) { | |
return Base64.getDecoder() | |
.decode(input); | |
} | |
private String urlDecode(String input) { | |
return URLDecoder.decode(input); | |
} | |
public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException { | |
TransformerFactory tf = TransformerFactory.newInstance(); | |
Transformer transformer = tf.newTransformer(); | |
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); | |
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); | |
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | |
transformer.transform(new DOMSource(doc), | |
new StreamResult(new OutputStreamWriter(out, "UTF-8"))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Script to uncompress drawio xml. Script can be executed using jbang.
Usage example:
With a
doc.drawio
file with following content:When
./decodeDiagram doc.drawio
is executed, following is displayed:(see the
*.drawio
content in a separated gist)See also: