当使用 lxml 渲染 XHTML 时,一切都很好,除非您碰巧使用 Firefox,它似乎无法处理以名称空间为前缀的 XHTML 元素和 javascript。虽然 Opera 能够很好地执行 javascript(这适用于 jQuery 和 MathJax),但无论 XHTML 命名空间是否有前缀 (h:
在我的例子中)或没有,在 Firefox 中脚本将因奇怪的错误而中止(this.head
未定义以 MathJax 为例)。
我知道关于register_namespace
函数,但它既不接受None
nor ""
作为命名空间前缀。我听说过_namespace_map
in the lxml.etree
模块,但我的Python抱怨这个属性不存在(版本问题?)
是否有其他方法删除 XHTML 命名空间的命名空间前缀?注意str.replace
正如另一个相关问题的答案中所建议的,是not这是我可以接受的方法,因为它不了解 XML 语义,并且可能很容易搞砸生成的文档。
根据要求,您会发现两个可供使用的示例。一与命名空间前缀 http://sotecware.net/files/persistent/so-lxml-xhtml/js-test-prefixed.xhtml and 一个没有 http://sotecware.net/files/persistent/so-lxml-xhtml/js-test.xhtml。第一个将在 Firefox 中显示 0(错误),第二个将显示 1(正确)。 Opera 将正确渲染两者。这显然是火狐浏览器的一个错误 https://bugzilla.mozilla.org/show_bug.cgi?id=492933,但这只是希望使用 lxml 实现无前缀 XHTML 的理由 – 还有其他很好的理由可以减少移动客户端等的流量(甚至h:
如果您考虑数十或数百个 html 标签,则数量相当多)。
Use ElementMaker
并给它一个nsmap
那个地图None
到您的默认名称空间。
#!/usr/bin/env python
# dogeml.py
from lxml.builder import ElementMaker
from lxml import etree
E = ElementMaker(
nsmap={
None: "http://wow/" # <--- This is the special sauce
}
)
doge = E.doge(
E.such('markup'),
E.many('very namespaced', syntax="tricks")
)
options = {
'pretty_print': True,
'xml_declaration': True,
'encoding': 'UTF-8',
}
serialized_bytes = etree.tostring(doge, **options)
print(serialized_bytes.decode(options['encoding']))
正如您在此脚本的输出中所看到的,定义了默认命名空间,但标签没有前缀。
<?xml version='1.0' encoding='UTF-8'?>
<doge xmlns="http://wow/">
<such>markup</such>
<many syntax="tricks">very namespaced</many>
</doge>
我已使用 Python 2.7.6、3.3.5 和 3.4.0 结合 lxml 3.3.1 测试了此代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)