什么是BeautifulSoup4加入我的SVG标签?

时间:2014-02-16 03:17:41

标签: xml python-3.x svg beautifulsoup

当我使用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>

1 个答案:

答案 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之类的内容在输出中为该命名空间设置空前缀。