当我使用BeautifulSoup4加载和转储一个非常简单的Inkscape SVG文件时,顶级SVG标记名称会附加:svg
,并且XML声明不再具有standalone="no"
。这导致W3C XML validator抱怨:
找不到DOCTYPE!仅检查XML语法。
这里到底发生了什么,为什么它会改变验证结果?如何在仍可以对SVG文件进行操作的同时保留其原始结构?
重现这一点的代码是:
Python 3.3.0 (default, Sep 25 2013, 19:28:08)
[GCC 4.7.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup
>>> with open('ex.svg') as ip: doc = BeautifulSoup(ip, 'xml')
...
>>> with open('out.svg', 'w') as op: op.write(doc.prettify())
...
560
>>>
原始SVG文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="0"
height="0"
id="template-svg"
version="1.1"
inkscape:version="0.48.4 r"
sodipodi:docname="template.svg">
</svg>
输出(手动美化一点):
<?xml version="1.0" encoding="utf-8"?>
<svg: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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="0"
height="0"
id="template-svg"
version="1.1"
inkscape:version="0.48.4 r"
sodipodi:docname="template.svg">
</svg:svg>
答案 0 :(得分:1)
顶级SVG标记名称附加
:svg
到底发生了什么,为什么它会改变验证结果?
这不是这里发生的事情。命名空间前缀正在改变,从无到有:
<svg
...
xmlns="http://www.w3.org/2000/svg"
到svg
:
<svg:svg
...
xmlns:svg="http://www.w3.org/2000/svg"
您的原始文档为SVG名称空间定义了两个单独的前缀:
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
您可能会发现删除第一个会导致输出始终使用原始svg:
前缀(实验上,会选择随机前缀)。
此更改不应对大多数XML使用者产生任何影响,但是您正在使用的验证程序。
为了更好地控制,请考虑使用lxml's BeautifulSoup parser以及this workaround之类的内容在输出中为该命名空间设置空前缀。