Probable bug with nested lists in v4.3.3
For nested lists in HTML, the nested list is supposed to be within an <li> element rather than as a child of the <ol> or <ul>. Given this first example of a slightly non-conformant HTML snippet produced by Gmail:
from lxml import etree html = etree.HTML('<ol><li>1</li><ol><li>2</li></ol></ol>') etree.tostring(html) b'<html><body><ol><li>1</li></ol><ol><li>2</li></ol></ol></body></html>'
The above code snippet works the way I would expect, in that even though the input isn't entirely valid html, the nested ordered list is still within the outer ordered list. However, if we look at this code snippet below, which is identical except for that now the nested list is an unordered list:
from lxml import etree html = etree.HTML('<ol><li>1</li><ul><li>*</li></ul></ol>') etree.tostring(html) b'<html><body><ol><li>1</li></ol><ul><li>*</li></ul></body></html>'
Suddenly the unordered list is no longer nested inside the ordered list. Unless there is something I don't know about in the HTML spec prohibiting nested lists of mixed types, this seems both inconsistent with the first example and broken in general. I would expect instead for lxml to produce one of the following two trees: <ol><li>1</li><ul><li>*</li></ul></ol> <ol><li>1</li><li><ul><li>*</li></ul></li></ol> Either would be fine, but what currently gets produced seems pretty suboptimal because it substantially changes the meaning of the text. Alex -- Alex Krupp Cell: (607) 351 2671 Read my Email: www.fwdeveryone.com/u/alex3917 Subscribe to my blog: http://alexkrupp.typepad.com/ My homepage: www.alexkrupp.com
Alex Krupp schrieb am 16.05.19 um 06:01:
For nested lists in HTML, the nested list is supposed to be within an <li> element rather than as a child of the <ol> or <ul>. Given this first example of a slightly non-conformant HTML snippet produced by Gmail:
from lxml import etree html = etree.HTML('<ol><li>1</li><ol><li>2</li></ol></ol>') etree.tostring(html) b'<html><body><ol><li>1</li></ol><ol><li>2</li></ol></ol></body></html>'
The above code snippet works the way I would expect, in that even though the input isn't entirely valid html, the nested ordered list is still within the outer ordered list.
However, if we look at this code snippet below, which is identical except for that now the nested list is an unordered list:
from lxml import etree html = etree.HTML('<ol><li>1</li><ul><li>*</li></ul></ol>') etree.tostring(html) b'<html><body><ol><li>1</li></ol><ul><li>*</li></ul></body></html>'
Suddenly the unordered list is no longer nested inside the ordered list.
Unless there is something I don't know about in the HTML spec prohibiting nested lists of mixed types, this seems both inconsistent with the first example and broken in general.
I would expect instead for lxml to produce one of the following two trees:
<ol><li>1</li><ul><li>*</li></ul></ol> <ol><li>1</li><li><ul><li>*</li></ul></li></ol>
Either would be fine, but what currently gets produced seems pretty suboptimal because it substantially changes the meaning of the text.
Sorry for not commenting on the issue itself, but since it's a matter of parsing non-standard HTML, the project to go to is libxml2, which implements the parser that lxml uses. Stefan
Am 19.05.2019, 15:29 Uhr, schrieb Stefan Behnel <stefan_ml@behnel.de>:
Alex Krupp schrieb am 16.05.19 um 06:01:
from lxml import etree html = etree.HTML('<ol><li>1</li><ul><li>*</li></ul></ol>') etree.tostring(html) b'<html><body><ol><li>1</li></ol><ul><li>*</li></ul></body></html>'
Suddenly the unordered list is no longer nested inside the ordered list.
Unless there is something I don't know about in the HTML spec prohibiting nested lists of mixed types, this seems both inconsistent with the first example and broken in general.
I would expect instead for lxml to produce one of the following two trees:
<ol><li>1</li><ul><li>*</li></ul></ol> <ol><li>1</li><li><ul><li>*</li></ul></li></ol>
Either would be fine, but what currently gets produced seems pretty suboptimal because it substantially changes the meaning of the text.
Sorry for not commenting on the issue itself, but since it's a matter of parsing non-standard HTML, the project to go to is libxml2, which implements the parser that lxml uses.
There are also alternative lxml-tree-producing HTML-Parsers like: https://github.com/kovidgoyal/html5-parser Maybe this one handles your cases better. --dirk
participants (3)
-
Alex Krupp -
Dirk Rothe -
Stefan Behnel