これを考慮してください:
import xml.etree.ElementTree as ET
xhtml = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML sample</title></head>
<body>
<p> Sample text</p>
</body>
</html>
'''
parser = ET.XMLParser()
parser.entity['nbsp'] = ' '
tree = ET.fromstring(xhtml, parser=parser)
print(ET.tostring(tree, method='xml'))
これは、xhtml
文字列の優れたテキスト表現をレンダリングします。
ただし、HTML5 doctypeを持つ同じXHTMLドキュメントの場合:
xhtml = '''<!DOCTYPE html>
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML sample</title></head>
<body>
<p> Sample text</p>
</body>
</html>
'''
例外が発生します:
xml.etree.ElementTree.ParseError: undefined entity: line 5, column 19
そのため、nbsp
エンティティdictに追加しましたが、パーサーはそれを処理できません。
私が使用した場合も同じことが起こりますlxml
:
from lxml import etree
parser = etree.XMLParser(resolve_entities=False)
tree = etree.fromstring(xhtml, parser=parser)
print etree.tostring(tree, method='xml')
上げる:
lxml.etree.XMLSyntaxError: Entity 'nbsp' not defined, line 5, column 26
エンティティを無視するようにパーサーを設定しましたが。
これはなぜですか。また、HTML5 doctype宣言を使用してXHTMLファイルの解析を可能にする方法を教えてください。
lxmlの部分的な解決策は、recovererを使用することです。
parser = etree.XMLParser(resolve_entities=False, recover=True)
しかし、私はまだより良いものを待っています。
ここでの問題は、バックグラウンドで使用されるExpatパーサーは通常、不明なエンティティを報告しないことです。エラーをスローするため、xml.etree.ElementTree
トリガーしようとしたフォールバックコードは実行されません。このUseForeignDTD
メソッドを使用してこの動作を変更できます。これにより、Expatはdoctype宣言を無視し、すべてのエンティティ宣言をに渡しますxml.etree.ElementTree
。次のコードは正しく機能します。
import xml.etree.ElementTree as ET
xhtml = '''<!DOCTYPE html>
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML sample</title></head>
<body>
<p> Sample text</p>
</body>
</html>
'''
parser = ET.XMLParser()
parser._parser.UseForeignDTD(True)
parser.entity['nbsp'] = u'\u00A0'
tree = ET.fromstring(xhtml, parser=parser)
print(ET.tostring(tree, method='xml'))
このアプローチの副作用:私が言ったように、doctype宣言は完全に無視されます。これは、Doctypeでカバーされていると思われるエンティティも含め、すべてのエンティティを宣言する必要があることを意味します。
ElementTree.XMLParser.entity
辞書に入力する値は通常の文字列である必要があることに注意してください。エンティティが置き換えられるテキストです。他のエンティティを参照することはできなくなります。だからそれはのu'\u00A0'
ためでなければなりません
。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加