Java - Recuperar fichero xml RAW de fichero xml Comprimido Draw.io

 
Vista:

Recuperar fichero xml RAW de fichero xml Comprimido Draw.io

Publicado por felipe (1 intervención) el 26/09/2018 22:41:12
Quieros recuperar el formato raw del xml comprimido que se salva por defecto draw.io, desde un programa en modo comandos.
Por ejemplo del fichero circuito.xml
1
2
3
4
<?xml version="1.0"?>
-<mxfile type="device" editor="www.draw.io" version="9.1.8" userAgent="Mozilla/5.0 (Windows NT 6.1; rv:61.0) Gecko/20100101 Firefox/61.0">
<diagram id="7e0a89b8-554c-2b80-1dc8-d5c74ca68de4" name="Page-1">7Ztdj9soFIZ/TS478neSy0maaS9aaaSRut2ritjEZouNhckk2V+/ .................
/xE0N38Aw==</diagram></mxfile>

quiero obtener
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
-<mxGraphModel shadow="0" math="0" background="#ffffff" pageHeight="850" pageWidth="1100" pageScale="1" page="1" fold="1" arrows="1" connect="1" tooltips="1" guides="1" gridSize="10" grid="1" dy="545" dx="1042">
-<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
......
......
......
<mxGeometry as="geometry" height="4" width="4" y="232" x="120"/>
</mxCell>
</root>
</mxGraphModel>


He buscado por la ayuda de draw.io, en google: convert draw xml raw
nos remite a la pagina https://about.draw.io/extracting-the-xml-from-mxfiles/
y de aqui a
https://jgraph.github.io/drawio-tools/tools/convert.html
con explorador de arhivos, sobre fic. circuito.xml, manteniendo click sobre el, los sueltas sobre recuadro "Drop files here"
click en [Decode] Y LO VES EN XML RAW
y aqui viendo el fuente de esta pagina que es JavaScript , vemos que usa xmlparser, atob () y pako.inflateRaw
1) data = getTextContent( diagrams[0]); // texto del XML
2) dataB = atob( data); // decode base-64 string to binary
3) dataC = bytesToString( pako.inflateRaw( dataB) ); // Inflate

Veo que usa la libreria JS de pako, para hacer inflateRaw , estudiando pako.js dice que usa ZLIB

He intentado hacerlo en Java, ya que hace unos años estudie java.


Estoy usando java 8, he llegado a hacer este programa LeeXMLZip.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// programa para java > 8, inflar (Zlib) .XML de fichero salvado de draw.io , uso c> java LeeXMLZip Circuito.xml <-|
// idea inicial de https://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
 
import java.nio.charset.StandardCharsets;
import java.util.Base64;
 
import java.io.File;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.* ;
 
 
 
 
public class LeeXMLZip {
 
 
	public static String decompress(byte[] compressed) throws IOException { // draw.io usa pako.js (basado en zlib port)
		ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
		InflaterInputStream gis = new InflaterInputStream(bis); // para descomprimir ZLIB
		BufferedReader br = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
		StringBuilder sb = new StringBuilder();
		String line;
		while((line = br.readLine()) != null) {
			sb.append(line);
		}
		br.close();
		gis.close();
		bis.close();
		return sb.toString();
	}
 
   public static String decode64(String value) throws Exception {
      byte[] decodedValue = Base64.getDecoder().decode(value);  // Basic Base64 decoding
      return new String(decodedValue, StandardCharsets.UTF_8);
   }
 
  public static void main(String argv[]) {
    try {
        for (String s: argv)
         {
//       System.out.println( s);
	 File fXmlFile = new File( s); // Fichero "Circuito.xml"
  	 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
	 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
	 Document doc = dBuilder.parse( fXmlFile);
	 doc.getDocumentElement().normalize();
//	 System.out.println("Raiz :" + doc.getDocumentElement().getNodeName());	// mxfile
	 NodeList nList = doc.getElementsByTagName("diagram");
	 for (int temp = 0; temp < nList.getLength(); temp++) {
		Node nNode = nList.item( temp);
//		System.out.println("\nCurrent Element :" + nNode.getNodeName()); // "diagram"
		if (nNode.getNodeType() == Node.ELEMENT_NODE) {
			Element eElement = (Element) nNode;
//			System.out.println("id =" + eElement.getAttribute("id")+" Texto="); // id =7e0a89b8-554c-2b80-1dc8-d5c74ca68de4
			String cuerpo = doc.getElementsByTagName("diagram").item(0).getTextContent(); // cuerpo
//			System.out.println( cuerpo);
                        byte[] decodedValue = Base64.getDecoder().decode( cuerpo);  // Base64 decoding string ascii to binary
//			System.out.println( decodedValue);
			String XmlUnzip= decompress( decodedValue );
//			System.out.println( XmlUnzip );
		}
	 }
        }
    } catch (Exception e) {
	e.printStackTrace();
    }
  }
}


---------------------------------------------- Ahora mismo tengo este error
He llegado hasta dataB, falla el paso 3)

Z:\CursoJava\pako\Zlib>java LeeXMLZip Circuito.xml
java.util.zip.ZipException: incorrect header check
at java.util.zip.InflaterInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at LeeXMLZip.decompress(LeeXMLZip.java:33)
at LeeXMLZip.main(LeeXMLZip.java:69)
Por favor, ¿algun experto me puede ayudar?
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Recuperar fichero xml RAW de fichero xml Comprimido Draw.io

Publicado por Tom (1831 intervenciones) el 27/09/2018 12:46:54
Tras un buen rato de pruebas y tal, he conseguido algo medianamente legible usando:
1
2
3
4
5
6
7
8
9
10
if(n.getNodeType() == Node.ELEMENT_NODE) {
		String text = ((Element)n).getTextContent();
		byte bytes[] = Base64.getDecoder().decode(text);
		byte tmp[] = new byte[1024];
		Inflater decomp = new Inflater(true);
		decomp.setInput(bytes);
		decomp.inflate(tmp);
		System.out.println(new String(tmp));
		decomp.end();
	  }
(O sea, pasándole un parámetro a Inflater, que es lo más parecido al "raw")
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar