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

如何正确将XML传递至draw.io/embed.diagrams.net?

如何正确将XML传递至draw.io/embed.diagrams.net?

我尝试创建了一个HTML示例,用来演示如何把XML内容发送到embed.diagrams.net(参考下方示例和draw.io官方的Embed Mode文档),但遇到了以下错误:

Not a diagram file (error on line 1 at column 1: Start tag expected, '<' not found)

错误提示截图

=> 如何修改代码才能正确地把XML内容传递给embed.diagrams.net?

我已经尝试过移除换行和其他空白字符,但没有解决问题。我也试过把XML编码成URI,用"#U"或"#R"参数传递给app.diagrams.net,但在iframe里无法生效。

(我的实际场景是要在JupyterLab 4里用IPython.display和IPython.HTML函数展示draw.io内容,在那之前我需要一个能正常运行的JavaScript示例。)


修复后的完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Diagrams.net Embed Demo</title>
</head>
<body>
<iframe id="embed-diagram" src="https://embed.diagrams.net/" width="100%" height="600px"></iframe>

<script>
    // Example draw.io XML content
    var xml = `<mxfile host="app.diagrams.net">
            <diagram name="Page-1">
                <mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
                    <root>
                        <mxCell id="0"/>
                        <mxCell id="1" parent="0"/>
                        <mxCell id="2" value="hello world" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                            <mxGeometry x="160" y="160" width="80" height="30" as="geometry"/>
                        </mxCell>
                    </root>
                </mxGraphModel>
            </diagram>
        </mxfile>
    `;          

    const iframe = document.getElementById('embed-diagram');

    window.addEventListener('message', function(event) {
        if (event.data === 'ready') {
            console.log('Iframe ready to receive data');

            // 关键修复:用JSON.stringify构造标准JSON消息,自动处理XML中的特殊字符
            var message = JSON.stringify({
                action: 'load',
                xml: xml
            });

            console.log(message);
            iframe.contentWindow.postMessage(message, '*');
        }
    });

    iframe.onload = function() {
        console.log('Iframe loaded');
        iframe.contentWindow.postMessage(JSON.stringify({
            action: 'init'
        }), '*');
    };
</script>
</body>
</html>

修复核心说明

  1. 避免手动拼接的语法错误:你之前手动拼接字符串" {action: 'load', xml: '"+ xml + "'}"时,XML里的双引号会和外层的双引号冲突,导致JSON直接解析失败,draw.io收到的是混乱的无效内容,自然识别不了是diagram文件。
  2. 标准化消息格式JSON.stringify会自动转义XML里的特殊字符(比如双引号转成\"),生成合法的JSON字符串,确保draw.io能正确解析并识别XML内容。

修复后,你就能得到和本地打开.drawio文件完全一致的效果:
正确显示的draw.io图形

对你的JupyterLab场景的提示

这个修复后的逻辑可以直接移植到JupyterLab中,你只需要把核心的HTML结构(iframe+script部分)用IPython.display.HTML()包裹,就能在Notebook里正常渲染draw.io图形了,核心就是始终通过JSON.stringify来构造postMessage的消息内容。

备注:内容来源于stack exchange,提问作者Stefan

火山引擎 最新活动