Pythonのxml.dom.minidomでDoctypeをレンダリングする方法は?
質問
私は試した:
document.doctype = xml.dom.minidom.DocumentType('html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"')
出力にはDoctypeはありません。手で挿入せずに修正する方法は?
解決
クラスをインスタンス化するべきではありません minidom
直接。それはAPIのサポートされている部分ではありません、 ownerDocument
Sは縛られず、奇妙な不正行為を得ることができます。代わりに、適切なDOMレベル2コアメソッドを使用します。
>>> imp= minidom.getDOMImplementation('')
>>> dt= imp.createDocumentType('html', '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd')
( 'dtd/xhtml1-strict.dtd'は一般的に使用されますが間違っています SystemId
. 。その相対URLは、w3.orgのxhtml1フォルダー内でのみ有効です。)
今、あなたは持っています DocumentType
ノード、ドキュメントに追加できます。標準によると、これを行う唯一の保証された方法は、ドキュメントの作成時間です。
>>> doc= imp.createDocument('http://www.w3.org/1999/xhtml', 'html', dt)
>>> print doc.toxml()
<?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/>
既存のドキュメントのDoctypeを変更したい場合、それはさらに問題です。 DOM標準はそれを必要としません DocumentType
NOのノード ownerDocument
ドキュメントに挿入可能になります。ただし、一部のDOMはそれを許可します。 pxdom
. minidom
それを許可します:
>>> doc= minidom.parseString('<html xmlns="http://www.w3.org/1999/xhtml"><head/><body/></html>')
>>> dt= minidom.getDOMImplementation('').createDocumentType('html', '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd')
>>> doc.insertBefore(dt, doc.documentElement)
<xml.dom.minidom.DocumentType instance>
>>> print doc.toxml()
<?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/><body/></html>
しかし、バグで:
>>> doc.doctype
# None
>>> dt.ownerDocument
# None
これはあなたにとって重要かもしれません。
技術的には、既存のドキュメントにDoctypeを設定する標準ごとに信頼できる唯一の方法は、新しいドキュメントを作成し、古いドキュメント全体をインポートすることです。
def setDoctype(document, doctype):
imp= document.implementation
newdocument= imp.createDocument(doctype.namespaceURI, doctype.name, doctype)
newdocument.xmlVersion= document.xmlVersion
refel= newdocument.documentElement
for child in document.childNodes:
if child.nodeType==child.ELEMENT_NODE:
newdocument.replaceChild(
newdocument.importNode(child, True), newdocument.documentElement
)
refel= None
elif child.nodeType!=child.DOCUMENT_TYPE_NODE:
newdocument.insertBefore(newdocument.importNode(child, True), refel)
return newdocument
所属していません StackOverflow