Python 在lxml中定义默认名称空间(未固定)
当使用lxml呈现XHTML时,一切都很好,除非您碰巧使用了Firefox,它似乎无法处理带有名称空间前缀的XHTML元素和javascript。尽管Opera能够很好地执行javascript(这适用于jQuery和MathJax),但无论XHTML名称空间是否有前缀(Python 在lxml中定义默认名称空间(未固定),python,xslt,xhtml,namespaces,lxml,Python,Xslt,Xhtml,Namespaces,Lxml,当使用lxml呈现XHTML时,一切都很好,除非您碰巧使用了Firefox,它似乎无法处理带有名称空间前缀的XHTML元素和javascript。尽管Opera能够很好地执行javascript(这适用于jQuery和MathJax),但无论XHTML名称空间是否有前缀(h:,在我的例子中),在Firefox中,脚本都会因奇怪的错误而中止(this.head在MathJax中未定义) 我知道register\u namespace函数,但它既不接受None也不接受“作为名称空间前缀。我在lxml
h:
,在我的例子中),在Firefox中,脚本都会因奇怪的错误而中止(this.head
在MathJax中未定义)
我知道register\u namespace
函数,但它既不接受None
也不接受“
作为名称空间前缀。我在lxml.etree
模块中听说了\u namespace\u map
,但是我的Python抱怨说这个属性不存在(版本问题?)
是否有其他方法删除XHTML名称空间的名称空间前缀?请注意,str.replace
,正如在对另一个相关问题的回答中所建议的那样,这不是我可以接受的方法,因为它不知道XML语义,并且可能很容易破坏结果文档
根据请求,您将找到两个可供使用的示例。一个有和。第一个将在Firefox中显示0(错误),第二个将显示1(正确)。Opera将正确地呈现这两种情况。这显然是,但这只是胡想用LXML预想的XHTML的理由——还有其他的理由来减少移动客户端的流量等(即使是代码> h:如果你考虑了几十或百个HTML标签),那么 从代码>内容>代码>中删除所有前缀,在维护根节点中定义的命名空间时:
import lxml.etree as ET
content = '''\
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE html>
<h:html xmlns:h="http://www.w3.org/1999/xhtml" xmlns:ml="http://foo">
<h:head>
<h:title>MathJax Test Page</h:title>
<h:script type="text/javascript"><![CDATA[
function test() {
alert(document.getElementsByTagName("p").length);
};
]]></h:script>
</h:head>
<h:body onload="test();">
<h:p>test</h:p>
<ml:foo></ml:foo>
</h:body>
</h:html>
'''
dom = ET.fromstring(content)
xslt = '''\
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<!-- identity transform for everything else -->
<xsl:template match="/|comment()|processing-instruction()|*|@*">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<!-- remove NS from XHTML elements -->
<xsl:template match="*[namespace-uri() = 'http://www.w3.org/1999/xhtml']">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
<!-- remove NS from XHTML attributes -->
<xsl:template match="@*[namespace-uri() = 'http://www.w3.org/1999/xhtml']">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
'''
xslt_doc = ET.fromstring(xslt)
transform = ET.XSLT(xslt_doc)
dom = transform(dom)
print(ET.tostring(dom, pretty_print = True,
encoding = 'utf-8'))
将lxml.etree作为ET导入
内容=“”\
MathJax测试页面
测试
'''
dom=ET.fromstring(内容)
xslt=''\
'''
xslt_doc=ET.fromstring(xslt)
transform=ET.XSLT(XSLT\u doc)
dom=变换(dom)
打印(ET.tostring)(dom,pretty_print=True,
编码='utf-8'))
屈服
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>MathJax Test Page</title>
<script type="text/javascript">
function test() {
alert(document.getElementsByTagName("p").length);
};
</script>
</head>
<body onload="test();">
<p>test</p>
<ml:foo xmlns:ml="http://foo"/>
</body>
</html>
MathJax测试页面
功能测试(){
警报(document.getElementsByTagName(“p”).length);
};
试验
使用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']))
#/usr/bin/env python
#多格姆
从lxml.builder导入ElementMaker
从lxml导入etree
E=元素制造者(
nsmap={
无:“http://wow/“#展开@neirbowj的答案,但使用ET.Element和ET.SubElement,并呈现一个混合名称空间的文档,其中根恰好是显式名称空间,子元素(通道
)是默认名称空间:
#我设置了但不使用默认名称空间:
root=ET.Element('{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF',nsmap={None:'http://purl.org/rss/1.0/'})
#我使用默认名称空间,将其URL包含在大括号中:
e=ET.SubElement(根,'{http://purl.org/rss/1.0/}频道')
打印(ET.tostring(root,xml_声明=True,encoding='utf8').decode())
这将打印出以下内容:
<?xml version='1.0' encoding='utf8'?>
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><channel/></rdf:RDF>
…我明白了:
<?xml version='1.0' encoding='utf8'?>
<doge:RDF xmlns:doge="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/"><channel/></doge:RDF>
示例XHTML可用吗?一个可供其他人测试/使用的小型自包含示例?我将在一分钟内设置一个示例。我不想删除所有名称空间,我想使其无前缀。xmlns
仍然需要存在。这更好,但仍然无效XHTML。有办法修复xmlns:h
attrib吗ute要成为xmlns
?没关系,我是通过在
中设置xmlns=“http://…/xhtml
来实现的。感谢您的输入,我将在添加内容中进行编辑并接受:)谢谢!这对创建文档很有帮助。但是,我的大部分输入来自XSL转换或加载的文件。这可能与其他人有关,因此+1OK。我不确定,因为您的问题提到“呈现XHTML”。
<?xml version='1.0' encoding='utf8'?>
<doge:RDF xmlns:doge="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/"><channel/></doge:RDF>