You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

嵌入式Draw.io编辑器导出XML丢失图标元数据的技术求助

嵌入式Draw.io编辑器导出XML丢失图标元数据的技术求助

我在自己的网页中嵌入了Draw.io在线编辑器,想要实现提取包含完整形状元数据的未压缩XML,但目前导出的XML内容不仅是压缩状态,解压后还丢失了图标(比如AWS EC2实例)的关键元数据信息,比如resIcon=mxgraph.aws4.ec2这类标识,以及形状的样式细节。

我的实现代码

下面是我当前的网页代码,通过iframe嵌入Draw.io,提供了提取XML的按钮:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Draw.io Editor Test</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            font-family: Arial, sans-serif;
        }
        #controls {
            margin-bottom: 10px;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
        }
        button:hover {
            background-color: #45a049;
        }
        #editor {
            width: 100%;
            height: 600px;
            border: 1px solid #ccc;
        }
        #output {
            margin-top: 20px;
            padding: 10px;
            background-color: #f5f5f5;
            border: 1px solid #ddd;
            border-radius: 4px;
            max-height: 300px;
            overflow: auto;
        }
        pre {
            margin: 0;
            white-space: pre-wrap;
            word-wrap: break-word;
        }
    </style>
</head>
<body>
    <h1>Draw.io Editor Test</h1>
    
    <div id="controls">
        <button onclick="extractXML()">Extract XML</button>
    </div>
    
    <iframe id="editor" src="https://embed.diagrams.net/?embed=1&ui=simple&proto=json&modified=0&libraries=1&saveAndExit=0&noSaveBtn=1&noExitBtn=1"></iframe>
    
    <div id="output"></div>

    <script>
        const iframe = document.getElementById('editor');
        let receivedXML = null;

        // Listen for messages from the iframe
        window.addEventListener('message', function(evt) {
            if (evt.data && typeof evt.data === 'string') {
                try {
                    const msg = JSON.parse(evt.data);
                    
                    console.log('Received message:', msg);
                    
                    // Handle the export response
                    if (msg.event === 'export') {
                        receivedXML = msg.data;
                        displayXML(receivedXML);
                    }
                    
                    // Handle init event - editor is ready, send load action to enable it
                    if (msg.event === 'init') {
                        console.log('Editor initialized, loading blank diagram');
                        iframe.contentWindow.postMessage(
                            JSON.stringify({
                                action: 'load',
                                autosave: 0,
                                xml: '<mxfile><diagram id="diagram1" name="Page-1"><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/></root></mxGraphModel></diagram></mxfile>'
                            }),
                            '*'
                        );
                    }
                } catch (e) {
                    // Not a JSON message, ignore
                    console.debug('Non-JSON message:', e);
                }
            }
        });

        function extractXML() {
            // Request XML export from the editor
            iframe.contentWindow.postMessage(JSON.stringify({
                action: 'export',
                format: 'xml',
                compressed: false
            }), '*');
        }

        function displayXML(xml) {
            const output = document.getElementById('output');
            output.innerHTML = '<h3>Extracted XML:</h3><pre>' + escapeHtml(xml) + '</pre>';
        }

        function escapeHtml(text) {
            const map = {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            };
            return text.replace(/[&<>"']/g, m => map[m]);
        }

        // Wait for iframe to load
        iframe.onload = function() {
            console.log('Iframe loaded');
        };
    </script>
</body>
</html>

问题细节对比

1. 本地Draw.io保存的完整XML(以AWS EC2图标为例)

当我在桌面版Draw.io中添加AWS EC2图标并保存为.drawio.xml,XML中包含完整的形状元数据:

<mxCell id="2" parent="1" style="sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.ec2;" value="" vertex="1">
  <mxGeometry height="78" width="78" x="161" y="161" as="geometry" />
</mxCell>

可以看到这里明确包含shape=mxgraph.aws4.resourceIconresIcon=mxgraph.aws4.ec2等关键元数据。

2. 我的代码导出并解压后的XML

通过代码中的export事件获取的msg.data是压缩字符串,解压后对应的形状节点丢失了这些元数据:

<mxCell
  id="2"
  parent="1"
  style="sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100"
  vertex="1">
  <mxGeometry x="904.5" y="644.5" width="79" height="79" as="geometry"/>
</mxCell>

这里不仅缺失了strokeColor=#ffffff等样式,更关键的是丢失了shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.ec2;这些标识图标的核心元数据。

我的疑问

我在extractXML()方法中已经指定了compressed: false,但为什么返回的XML还是压缩的?并且解压后丢失了这么多关键信息?应该如何修改代码,才能获取到和本地保存一致的、包含完整元数据的未压缩XML?

火山引擎 最新活动