使用lxml生成XHTML文档的推荐方式是什么?

11

Python库lxml似乎提供了几个构建器用于生成HTML文档,它们之间有什么区别?

但是这些构建器生成的是普通的HTML,而不是XHTML。虽然我可以手动添加xmlns声明,但这样做不够优雅。那么使用lxml生成XHTML文档的推荐方式是什么?

lxml.builder.E

来自http://lxml.de/tutorial.html#the-e-factory的示例:

>>> from lxml.builder import E

>>> def CLASS(*args): # class is a reserved word in Python
...     return {"class":' '.join(args)}

>>> html = page = (
...   E.html(       # create an Element called "html"
...     E.head(
...       E.title("This is a sample document")
...     ),
...     E.body(
...       E.h1("Hello!", CLASS("title")),
...       E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
...       E.p("This is another paragraph, with a", "\n      ",
...         E.a("link", href="http://www.python.org"), "."),
...       E.p("Here are some reserved characters: <spam&egg>."),
...       etree.XML("<p>And finally an embedded XHTML fragment.</p>"),
...     )
...   )
... )

lxml.html.builder

示例来自http://lxml.de/lxmlhtml.html#creating-html-with-the-e-factory

>>> from lxml.html import builder as E
>>> from lxml.html import usedoctest
>>> html = E.HTML(
...   E.HEAD(
...     E.LINK(rel="stylesheet", href="great.css", type="text/css"),
...     E.TITLE("Best Page Ever")
...   ),
...   E.BODY(
...     E.H1(E.CLASS("heading"), "Top News"),
...     E.P("World News only on this page", style="font-size: 200%"),
...     "Ah, and here's some more text, by the way.",
...     lxml.html.fromstring("<p>... and this is a parsed fragment ...</p>")
...   )
... )

2
你列出了两种不同的方法,你对其中任何一种方法有问题或反对吗?帮助我们知道这个问题的“正确”答案是什么样的。 - Mike Pennington
我认为两种方法都可以工作。选择其中一种并使用它即可。不过,你的问题似乎更多基于个人意见,而不是真正的针对性问题,我建议关闭这个问题。 - Jan Vlcinsky
3个回答

3
混合使用ElementMaker和lxml.builder中的E对我来说很管用:
from lxml import etree
from lxml.builder import ElementMaker,E

M=ElementMaker(namespace=None,
               nsmap={None: "http://www.w3.org/1999/xhtml"})
html = M.html(E.head(E.title("Test page")),
              E.body(E.p("Hello world")))
result = etree.tostring(html,
                        xml_declaration=True,
                        doctype='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
                        encoding='utf-8',
                        standalone=False,
                        with_tail=False,
                        method='xml',
                        pretty_print=True)
print result

结果是:
<?xml version='1.0' encoding='utf-8' standalone='no'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test page</title>
  </head>
  <body>
    <p>Hello world</p>
  </body>
</html>

1
Python库lxml提供了多个构建器用于生成HTML文档。它们之间有何区别? lxml.builder.E使用工厂模式。
```python from lxml.html import builder as E from lxml.html import usedoctest html = E.HTML( E.HEAD( E.LINK(rel="stylesheet", href="great.css", type="text/css"), E.TITLE("Best Page Ever") ), E.BODY( E.H1(E.CLASS("heading"), "Top News"), E.P("World News only on this page", style="font-size: 200%"), "Ah, and here's some more text, by the way.", lxml.html.fromstring("

... and this is a parsed fragment ...

") ) ) ``` lxml.builder使用原型模式:
从lxml.builder导入E
def CLASS(*args): # class是Python中的保留字 return {"class":' '.join(args)}
html = page = ( E.html( # 创建一个名为“html”的元素 E.head( E.title("这是一个示例文档") ), E.body( E.h1("你好!", CLASS("title")), E.p("这是一个带有", E.b("粗体"), "文本的段落!"), E.p("这是另一个段落,其中包含一个", "\n ", E.a("链接", href="http://www.python.org"), "。"), E.p("这里有一些保留字符:."), etree.XML("

最后是嵌入的XHTML片段。

"), ) ) )

虽然我可以手动添加xmlns声明,但那样不优雅。

XSLT将是另一个选项。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" encoding="utf-8" version="" indent="yes" standalone="no" media-type="text/html" omit-xml-declaration="no" doctype-system="about:legacy-compat" />
<xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml">
    <xsl:copy-of select="."/>
  </html>
</xsl:template>
</xsl:stylesheet>

参考资料


0
Python库lxml似乎提供了几个构建器来生成HTML文档。它们之间有什么区别? lxml.builder.E生成一个XML文档,其类为,这意味着该对象不知道自己是HTML文档(也可能不是)。 lxml.html.builder生成一个,这意味着您拥有一个知道自己是HTML的对象,并提供专门用于HTML的方法和属性,例如e.body或e.make_links_absolute(),详见https://lxml.de/api/lxml.html.HtmlMixin-class.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接