最近再做一个项目的时候需要处理svg文件:
SVG是一种图形文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形。它是基于XML(Extensible Markup Language),由World Wide Web Consortium(W3C)联盟进行开发的。严格来说应该是一种开放标准的矢量图形语言,可让你设计激动人心的、高分辨率的Web图形页面。用户可以直接用代码来描绘图像,可以用任何文字处理工具打开SVG图像,通过改变部分代码来使图像具有交互功能,并可以随时插入到HTML中通过浏览器来观看。
上面是百度百科的介绍,网上的svg处理的代码基本都是基于xml.etree.ElementTree,参考链接:https://blog.csdn.net/u010841775/article/details/102365829
具体代码:
import xml.etree.ElementTree as ET tree = ET.ElementTree(file="../../source_data/test.svg") # 根节点 root = tree.getroot() # 标签名 print('root_tag:', root.tag) # gs = root.findall('g') for stu in root.iter('{http://www.w3.org/2000/svg}g'): # 属性值 print("stu_name:", stu.attrib["name"]) if stu.tag == '{http://www.w3.org/2000/svg}g': print(stu.text) print(stu.tag) tree.write(r'../../source_data/update.svg',encoding='utf-8', xml_declaration=True)
上面的代码获取文件内容以及各个节点没问题,但是在写入文件之后文件就会增加ns0, ns1等各个节点。
原始的文件如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="1600" height="800" viewBox="0 0 423.33332 211.66666" version="1.1" id="svg8" inkscape:version="0.92.4 (5da689c313, 2019-01-14)" sodipodi:docname="欣晶玻璃模拟图.svg"> <defs id="defs2" /> <sodipodi:namedview id="base" pagecolor="#000000" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="0.92409204" inkscape:cx="793.72599" inkscape:cy="-174.99653" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1920" inkscape:window-height="1018" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" units="px" inkscape:pagecheckerboard="0" inkscape:snap-global="true" inkscape:snap-bbox="false" inkscape:bbox-paths="false" inkscape:snap-page="false" inkscape:snap-text-baseline="false" inkscape:snap-center="false" /> <metadata id="metadata5"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,470.99997)"> </g> </svg>
文件处理之后丢给前段,前端告诉我文件不能解析了,看了一下处理之后的文件变成了下面的样子(添加了ns0,ns1,ns2):
<?xml version='1.0' encoding='utf-8'?> <ns0:svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="http://www.w3.org/2000/svg" xmlns:ns1="http://www.inkscape.org/namespaces/inkscape" xmlns:ns2="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:ns4="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" width="1600" height="800" viewBox="0 0 423.33332 211.66666" version="1.1" id="svg8" ns1:version="0.92.4 (5da689c313, 2019-01-14)" ns2:docname="欣晶玻璃模拟图.svg"> <ns0:defs id="defs2" /> <ns2:namedview id="base" pagecolor="#000000" bordercolor="#666666" borderopacity="1.0" ns1:pageopacity="0" ns1:pageshadow="2" ns1:zoom="0.92409204" ns1:cx="793.72599" ns1:cy="-174.99653" ns1:document-units="px" ns1:current-layer="layer1" showgrid="false" ns1:window-width="1920" ns1:window-height="1018" ns1:window-x="-8" ns1:window-y="-8" ns1:window-maximized="1" units="px" ns1:pagecheckerboard="0" ns1:snap-global="true" ns1:snap-bbox="false" ns1:bbox-paths="false" ns1:snap-page="false" ns1:snap-text-baseline="false" ns1:snap-center="false" /> <ns0:metadata id="metadata5"> <rdf:RDF> <ns4:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title /> </ns4:Work> </rdf:RDF> </ns0:metadata> <ns0:g ns1:label="Layer 1" ns1:groupmode="layer" id="layer1" transform="translate(0,470.99997)"> </ns0:g> </ns0:svg>
这尼玛就很蛋疼了。
要解决这个问题其实是需要重新定义namespace, 添加以下代码:
ET.register_namespace("","http://www.w3.org/2000/svg") # svg 默认namespace 为空 ET.register_namespace("sodipodi","http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd") # 根据源文件重新定义namespace ET.register_namespace("inkscape","http://www.inkscape.org/namespaces/inkscape")# 根据源文件重新定义namespace
添加以上内容之后,重新写入文件就一切ok了(ns0虽然前端不能解析,但是浏览器是可以正常预览的)。
4 comments
你的图片在 RSS 阅读器里不显示。如果也是用 CDN 加了防盗链的话,要增加一个判断条件是 Referer > 0 才阻断。
oss把空refer给禁了。打开了 应该能看到了
最下方图黄字看不清楚!
嗯嗯,截图的时候黄色和红色很容易截图之后就胡了。不过那个具体的内容不关键,问题解决了就ok了。