在实现笔记接入私有化部署的drawio时,发现一个有意思的现象:使用draw绘图之后,在笔记系统中保存的是一个svg文件,在编辑时drawio能够恢复完整的绘图信息,甚至包括了多页。
于是查找了关于SVG文件导入和解析相关的代码实现以及SVG文件中的XML数据格式和解析的实现,最后发现了其中的奥秘。
之所以drawio能从SVG恢复成完整图形,是因为SVG文件中包含了完整的图形数据。drawio导出的SVG文件实际上是在SVG中嵌入了完整的 mxfile 格式数据
<mxfile host="..." modified="..." agent="..." version="..." type="device">
<diagram name="Page-1" id="...">
<mxGraphModel ...>
<!-- 完整的图形数据 -->
</mxGraphModel>
</diagram>
</mxfile>
导出为svg时,将mxfile格式数据转义之后,绑定在svg的content属性中。
<svg
xmlns="http://www.w3.org/2000/svg"
style="background: transparent; background-color: transparent; color-scheme: light dark;"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="141px"
height="142px"
viewBox="-0.5 -0.5 141 142"
content="<mxfile host="127.0.0.1" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36" version="26.2.2" pages="2"><diagram id="DSegkkja8PWRIwR6XoIs" name="Page-1">vZXBcoMgEIafxrtCNMk1aZoe2ukhh56JbIUpioMYtU9fLBg1phMPTi/O8u8u7n6s6OF9Wh8VydmbpCA85NPaw08eQmGwMs9WaKyw8X0rJIpTKwW9cOLf4MQurOQUilGgllJono/FWGYZxHqkEaVkNQ77lGL81pwkMBFOMRFT9YNTzVwXaN3rL8AT1r05iLbWk5Iu2HVSMEJlNZDwwcN7JaW2VlrvQbTsOi427/kP77UwBZmek4BswoWI0vXm6tJN16xJMFzNYlcxruGUk7j1VOZkjcZ0KswqMCYpcgv7k9dg9t9Ni3H1XUBpqAeSK+4IMgWtGhPSebcOlJsUhN26GnB3Ehsg7zTiTjq57tzDMIbjcZ8NfszGHF/emrmSMRTFY0ZnEn8lSpYZfS+14Bk4fQFUaHWDKpyiCtAdVtECrFZTVofQ22Jvs7lj3GJUTKbncga+JTD5Y0zB+v8mKpw/UXFjpoOCwjNmqh0noK/nR0NW2Is0CBf6NqObgUNTktEyJM2yvxN/fYMfCz78AA==</diagram><diagram id="g9qJdJroN9i7Zbt9pWF9" name="Page-2">xZRRT4MwEIB/DY8mg04nj9uc+KDRuAcfTQcnNCscKYfAfr1F2gEji5osMUuW9ruj3H0tddg6rQPF8+QJI5CON4tqh905nnftzvV/C5oO3M5mHYiViDrk9mArDmCgTStFBMUokRAliXwMQ8wyCGnEuFJYjdM+UI7fmvMYJmAbcjmlbyKixHThLXr+ACJO7JvdG7+LpNwmm06KhEdYDRDbOGytEKkbpfUaZOvOeumeuz8TPRamIKPfPPBaXov5XDVqFewLeN9c+Y9PV2aVTy5L03Dw3P5MydRYD7r6vB3mCkMotNRVlQiCbc7DFld68zVLKJV65urhjof7WGGZRc8lSZGB4dOybQ2gCOoBMm0EgCmQanSKjS6MUnOmPGbmVb9DrtWeDHbnxjBuDkV8XLr3pgdG3R80ehONZwWSNgUHbJdb5aCELgDUkL/08CfHH6IG+81cyq1/4vb2v92yidtlSKjOCi5T2SWwVdu20N/yI9+BfMFCkMBMp+yQCNNBwlKKuA0QnhjG7uyuj7fL7DKaj7eC1exPNbPLWNbT/pL5jg1uarb5Ag==</diagram></mxfile>">
<!-- 完整的svg标签 -->
</svg>
其中,图形数据的存储结构:
- mxfile 标签是最外层容器
- diagram 标签定义了每个页面
- mxGraphModel 包含了具体的图形数据,包括:
- 节点位置和大小
- 连线信息
- 样式定义
- 文本内容
- 分组关系
另外,drawio在导入svg时的恢复机制如下
- 当打开SVG文件时,drawio会:
- 解析SVG文件中的XML内容
- 提取其中的 mxfile 数据
- 从 mxGraphModel 中还原完整的图形结构
- 重建所有页面和图形元素
这就是为什么即使是SVG文件,也能完整恢复成drawio可编辑的图形,包括多页面、图层等高级特性。因为SVG文件中实际保存了两份数据:
- 用于显示的SVG图形数据
- 用于编辑的完整drawio图形数据
这种方式给我