Comment rendre un type de document avec xml.dom.minidom Python?
Question
J'ai essayé:
document.doctype = xml.dom.minidom.DocumentType('html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"')
Il n'y a pas doctype dans la sortie. Comment fixer sans l'insérer manuellement?
La solution
Vous ne devriez pas instancier des classes de minidom
directement. Ce n'est pas une partie prise en charge de l'API, le s ownerDocument
ne ligoter et vous pouvez obtenir des inconduites étranges. Au lieu d'utiliser les DOM niveau 2 méthodes appropriées de base:
>>> 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 'est un SystemId
couramment utilisé, mais mal. Cette URL relative ne serait valide dans le dossier xhtml1 à w3.org.)
Maintenant, vous avez un nœud DocumentType
, vous pouvez l'ajouter à un document. Selon la norme, la seule façon garantie de le faire est au moment de la création le document:
>>> 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/>
Si vous voulez modifier le DOCTYPE d'un document existant, qui est plus de problèmes. La norme DOM ne nécessite pas que les nœuds de DocumentType
sans ownerDocument
être inséré dans un document. Cependant, certains permettent DOMs, par exemple. pxdom
. minidom
genre permet de:
>>> 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>
mais avec des bugs:
>>> doc.doctype
# None
>>> dt.ownerDocument
# None
qui peut ou pas d'importance pour vous.
Techniquement, le seul moyen fiable par la norme pour définir un type de document sur un document existant est de créer un nouveau document et importer l'ensemble de l'ancien document en elle!
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