Python lxml和<;wbr>;标签
默认情况下,lxml不低于用于在长单词中添加分词符的TSA和wbr标记。它将其格式化为Python lxml和<;wbr>;标签,python,html,lxml,wbr,Python,Html,Lxml,Wbr,默认情况下,lxml不低于用于在长单词中添加分词符的TSA和wbr标记。它将其格式化为,而它应该简单地格式化为,类似于br标记 如何将此行为添加到lxml?由于仅存在于HTML5中,我认为正确的做法是使用lxml.html.html5parser 除此之外,空标记列表是在常规Python代码中定义的,因此您可以随时对其进行monkeypatch;看见我确信,补丁是受欢迎的。:) 好消息!这是完全不可能的。HTML标记名为 而lxml.html.html5parser包含两个严重的bug,它们的修
,而它应该简单地格式化为
,类似于br标记
如何将此行为添加到lxml?由于
仅存在于HTML5中,我认为正确的做法是使用lxml.html.html5parser
除此之外,空标记列表是在常规Python代码中定义的,因此您可以随时对其进行monkeypatch;看见我确信,补丁是受欢迎的。:) 好消息!这是完全不可能的。HTML标记名为 而
lxml.html.html5parser
包含两个严重的bug,它们的修复还没有发布
但是见鬼,让我们在本地修复它们,看看会发生什么
>>> lxml.html.tostring(lxml.html.html5parser.fromstring('<p>hello<wbr>world!</p>'), encoding=unicode)
u'<html:p xmlns:html="http://www.w3.org/1999/xhtml">hello<html:wbr></html:wbr>world!</html:p>'
>>lxml.html.tostring(lxml.html.html5parser.fromstring(“helloworld!”),encoding=unicode)
你这个世界
如此接近,却又如此遥远。至少结构是正确的
再试一次:
>>> lxml.html.tostring(lxml.html.html5parser.fromstring('<p>hello<wbr>world!</p>', parser=lxml.html.html5parser.HTMLParser(namespaceHTMLElements=False)), encoding=unicode)
u'<p>hello<wbr></wbr>world!</p>'
>>lxml.html.tostring(lxml.html.html5parser.fromstring(“helloworld!”,parser=lxml.html.html5parser.HTMLParser(namespacehtmlements=False)),encoding=unicode)
你好 "
好的
至少没有错
我想我可能会针对lxml和libxml2提交一些bug。实际上,修补libxml2并不困难(本演练是在Ubuntu 11.04上用Python 2.7.3完成的) 首先定义一个测试程序
wbr\u test.py
:
from lxml import etree
from cStringIO import StringIO
wbr_html = """\
<html>
<head>
<title>wbr test</title>
</head>
<body>
Test for a breakable<wbr>word implemenation change
</body>
</html>
"""
parser = etree.HTMLParser()
tree = etree.parse(StringIO(wbr_html), parser)
result = etree.tostring(tree.getroot(),
pretty_print=True, method="html")
if result.split() != wbr_html.split(): # split, as we are not interested in whitespace differences
print(result)
print("not ok")
else:
print("OK")
安装和安装python libxml2绑定:
sudo make install
cd to_python_bindings
sudo python setup.py install
再次测试您的wbr_Test.py
,确保它在最新的libxml2版本中失败
首先复制HTMLparser.c
,例如在/var/tmp
中
现在在libxml2源代码的顶层编辑文件HTMLparser.c。搜索单词强制
(仅出现一次)。您将看到
标记定义。从刚找到的那一行开始复制这三行。最合适的插入点就在末尾之前(在
的定义之后)。要在表中正确地获得最后一个逗号,请在只有'}'的那一行前面插入三行
而不是'};'代码>
在新插入的代码中,将br
替换为wbr
,并将DECL clear\u attrs
更改为NULL
(假设新标记没有弃用的属性)
结果应与/var/tmp
(diff-u HTMLparser.c/var/tmp
)中的版本不同,如下所示:
@@ -1039,6 +1039,9 @@
},
{ "var", 0, 0, 0, 0, 0, 0, 1, "instance of a variable or program argument",
DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "wbr", 0, 2, 2, 1, 0, 0, 1, "possible line break ",
+ EMPTY , NULL , DECL core_attrs, NULL , NULL
}
};
制作和安装:
make && sudo make install
再次测试您的wbr\u Test.py
。如果显示OK
作为快速修复,为什么不使用replace
字符串方法删除关闭标记
>>> t = 'Thisisa<wbr></wbr>test'
>>> t.replace('</wbr>', '')
'Thisisa<wbr>test'
>t='thisistest'
>>>t.替换('','')
“这是个测试”
@bukzor:“br”也在特殊的内联标签中
。。。您可能需要将“wbr”monkeypatch也导入其中。您可能需要先导入defs
,然后再导入lxml中的任何其他内容,否则其他模块将导入旧值。我不确定您的应用程序,但您可以简单地删除结束标记吗?非常酷!您能否确认,仅通过运行时配置无法获得类似的结果?用另一种方式来表达相同的问题:libxml2是否不允许对您修补的列表进行运行时配置?我真的想知道,如果不重新构造源代码,libxml2是否可以实现这一点。这些定义位于静态常量元素表中,该表不会复制到更动态的结构中,而是按原样使用。从C语言向这样的表中添加条目是不可能的,因此从Python语言是不可能的。谢谢Anthon。这似乎相当权威。你是否有任何线索,如果这种重组将被赞赏,上游?重组可能有点过火。HTML是唯一一种类似XML的语言,具有这样的标记特定语义;这里的问题只是HTML5添加了更多的标记,而libxml2只知道HTML4。添加新的标记和指定要使用的HTML版本的方法肯定就足够了。
>>> t = 'Thisisa<wbr></wbr>test'
>>> t.replace('</wbr>', '')
'Thisisa<wbr>test'