【发布时间】:2018-04-06 04:18:05
【问题描述】:
(在我问我的问题之前,请耐心等待下面的小故事!)
我有一些由 MathJax 生成的 SVG 元素,生成后看起来像这样(在元素检查器中可以找到):
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="6.768ex" height="2.468ex" viewBox="0 -825.2 2914.1 1062.4">
<defs>...</defs>
<g>...</g>
</svg>
当我尝试在 chrome 或 safari 中单独显示此 SVG 时,浏览器显示以下错误消息:
此 XML 文件似乎没有任何关联的样式信息。文档树如下所示。 [...]
经过一些实验,我发现罪魁祸首是缺少 'xmlns' 标签。 (我猜 MathJax 在具有此标签的页面中将另一个 SVG 放在更高的位置,因此在网页内,它不需要第二次重复。或者其他什么。)即,将开头的 <svg> 标签更改为此允许浏览器自行显示 SVG:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="6.768ex" height="2.468ex" viewBox="0 -825.2 2914.1 1062.4">
<defs>...</defs>
<g>...</g>
</svg>
(注意新的xmlns 属性。)
好的。很好。
现在我想自动执行添加缺少的xmlns 标记的任务。我想为此使用 python lxml 实用程序。
不幸的是(终于来了我的问题!),lxml 似乎隐藏了所有以 'xmlns' 开头的属性,我不知道为什么。虽然它允许我添加“xmlns”属性(例如,通过做
root.attrib['xmlns'] = "http://www.w3.org/2000/svg"
其中root 是文档的根<svg> 标记),我无法测试'xmlns' 属性是否已经存在,实际上如果我在同一个文件上运行脚本两次,这会导致两个单独的xmlns 标签被添加,这反过来又导致 lxml 抱怨和崩溃。
所以:(i) 为什么 lxml 对我隐藏某些属性,以及 (ii) 无论如何我如何才能添加 xmlns 标记,除非它已经不存在? (当然我可以手动解析文件,但我想要一个使用 lxml 的独立解决方案。)
【问题讨论】:
-
xmlns="..."并不是真正的属性;它是一个命名空间声明。因此在attrib中找不到它。 -
也许问题是您正在使用文本复制/粘贴操作从 MathJax 输出复制此 XML 子树,而正是此复制操作丢失了范围内的命名空间?在这种情况下,答案可能是找到一种可识别 XML 的方法来提取 SVG 子树?
-
问题是 MathJax 没有生成有效的 SVG,至少在浏览器 POV 中有效。如果没有限定所有标记和属性名称的命名空间,浏览器将不知道如何处理文档。没有 SVG 命名空间的标签
svg可能意味着任何东西。所以真正的问题是:如何让 MathJax 生成浏览器可以理解的 SVG? -
@MichaelKay 复制粘贴操作以打开
<svg>标记开始,以关闭</svg>标记结束。信息不会在那里丢失。问题是:当我使用lxml加载一个xml 文档时,我没有发现根元素是否已经包含xmlns属性的方法...... -
@LutzHorn (有趣的是,当它嵌入到较大的 html 文档中时,浏览器不会抱怨 MathJax 的 svg。它只会在 SVG 独立时抱怨。但这是一个谜MathJax 的人无疑应该能够解释。)