използвайки html5lib с xml.etree.ElementTree

Имам нужда от начин да използвам парсера html5lib за генериране на истински xml.etree.ElementTree. (lxml не е опция от съображения за преносимост.)

ELementTree.parse може да приеме анализатор като незадължителен параметър

xml.etree.ElementTree.parse(source, parser=None)

но не е ясно как би изглеждал такъв анализатор. Има ли клас или обект в рамките на HTML5, който мога да използвам за аргумента parser? Документацията за двете библиотеки по този въпрос е оскъдна.


Контекст:

Имам деформиран XHTML файл, който не може да бъде анализиран с ElementTree.parse:

<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title></head>
<body><div class="cls">Note that this br<br>is missing a closing slash</div></body>
</html>

Затова използвах html5lib.parse вместо параметъра по подразбиране treebuilder="etree", който работи добре.

Но html5lib очевидно не извежда xml.etree.ElementTree обект, а само един с почти идентичен API. Има два проблема с това:

Така че не мога да използвам нито ElementTree, нито html5lib самостоятелно.


person Arithmomaniac    schedule 26.12.2013    source източник


Отговори (2)


Дадено xml.etree.ElementTree като etree (както обикновено се импортира като):

Връщаното не е etree.ElementTree, а по-скоро etree.Element (това е същото като това, което връща etree.fromstring; само etree.parse връща etree.ElementTree). Той наистина е част от модула etree — не е нещо с подобен API. Проблемът, с който се сблъскахте, се отнася както за etree.fromstring, така и за html5lib.

В документацията на Python за xml.etree.ElementTree не се споменава аргументът namespaces — изглежда, че е недокументирана характеристика на ElementTree обекти (но не и Element обекти). Като такъв вероятно не е нещо, на което наистина трябва да се разчита! Най-добрият ви залог вероятно ще бъде да използвате функция за обвиване.

Фактът, че Eclipse не може да премине през дърветата, се дължи на факта, че html5lib по подразбиране е xml.etree.cElementTree, когато съществува — което е предназначено да бъде идентично според документацията на модула, но е внедрено в C с помощта на API на CPython, спирайки функционирането на дебъгера на Eclipse. Можете да получите дървостроител, като използвате неускорената версия (забележка от Python 3.3 и двете са реализация на C — cElementTree просто оцелява като остарял псевдоним), като използвате следното:

import xml.etree.ElementTree as etree
import html5lib

tb = html5lib.getTreeBuilder("etree", implementation=etree)
p = html5lib.HTMLParser(tb)
tree = p.parse("<html>")
person gsnedders    schedule 28.12.2013
comment
@Arithmomaniac Благодаря за казаното — редактирах го, за да отрази това. - person gsnedders; 29.12.2013

Трябва да увиете отговора в ElementTree

>>> from xml.etree.ElementTree import ElementTree
>>> from html5lib import parse
>>>
>>> ElementTree(parse("<html>"))
<xml.etree.ElementTree.ElementTree at 0x...>
person reubano    schedule 18.07.2016