read - Python xml minidom. generar elemento<text> Some text</ text>
xml etree elementtree tutorial (6)
¿Se puede hacer esto fácilmente?
Depende de la regla exacta que desee, pero generalmente no, tiene poco control sobre la impresión bonita. Si quiere un formato específico, generalmente tendrá que escribir su propio andador.
El formato de parámetro DOM Level 3 LS-pretty-print en pxdom se acerca mucho a tu ejemplo. Su regla es que si un elemento contiene un solo TextNode, no se agregará ningún espacio en blanco adicional. Sin embargo, (actualmente) utiliza dos espacios para una sangría en lugar de cuatro.
>>> doc= pxdom.parseString(''<a><b>c</b></a>'')
>>> doc.domConfig.setParameter(''format-pretty-print'', True)
>>> print doc.pxdomContent
<?xml version="1.0" encoding="utf-16"?>
<a>
<b>c</b>
</a>
(Ajuste el formato de codificación y salida para cualquier tipo de serialización que esté haciendo).
Si esa es la regla que deseas, y puedes salirte con la tuya, también podrías mapear mono de Minidom Element.writexml, por ej .:
>>> from xml.dom import minidom
>>> def newwritexml(self, writer, indent= '''', addindent= '''', newl= ''''):
... if len(self.childNodes)==1 and self.firstChild.nodeType==3:
... writer.write(indent)
... self.oldwritexml(writer) # cancel extra whitespace
... writer.write(newl)
... else:
... self.oldwritexml(writer, indent, addindent, newl)
...
>>> minidom.Element.oldwritexml= minidom.Element.writexml
>>> minidom.Element.writexml= newwritexml
Se aplican todas las advertencias habituales sobre la maldad del parche de monos.
tengo el siguiente código.
from xml.dom.minidom import Document
doc = Document()
root = doc.createElement(''root'')
doc.appendChild(root)
main = doc.createElement(''Text'')
root.appendChild(main)
text = doc.createTextNode(''Some text here'')
main.appendChild(text)
print doc.toprettyxml(indent=''/t'')
El resultado es:
<?xml version="1.0" ?>
<root>
<Text>
Some text here
</Text>
</root>
Todo esto está bien y elegante, pero ¿y si quiero que la salida se vea así?
<?xml version="1.0" ?>
<root>
<Text>Some text here</Text>
</root>
¿Se puede hacer esto fácilmente?
Orjanp ...
El paquete pyxml ofrece una solución simple para esto utilizando la función xml.dom.ext.PrettyPrint (). También puede imprimir en un descriptor de archivo.
Pero el paquete pyxml ya no se mantiene.
Oerjan Pettersen
Estaba buscando exactamente lo mismo, y me encontré con esta publicación. (el sangrado proporcionado en xml.dom.minidom rompió otra herramienta que estaba usando para manipular el XML, y necesitaba que se sangrara) Intenté la solución aceptada con un ejemplo un poco más complejo y este fue el resultado:
In [1]: import pxdom
In [2]: xml = ''<a><b>fda</b><c><b>fdsa</b></c></a>''
In [3]: doc = pxdom.parseString(xml)
In [4]: doc.domConfig.setParameter(''format-pretty-print'', True)
In [5]: print doc.pxdomContent
<?xml version="1.0" encoding="utf-16"?>
<a>
<b>fda</b><c>
<b>fdsa</b>
</c>
</a>
El bonito XML impreso no está formateado correctamente, y no estoy muy contento con el parche de mono (es decir, apenas sé lo que significa, y entiendo que es malo), así que busqué otra solución.
Estoy escribiendo la salida en el archivo, así que puedo usar el programa xmlindent para Ubuntu ($ sudo aptitude install xmlindent). Así que solo escribo el formato sin formato en el archivo, luego llamo a xmlindent desde dentro del programa python:
from subprocess import Popen, PIPE
Popen(["xmlindent", "-i", "2", "-w", "-f", "-nbe", file_name],
stderr=PIPE,
stdout=PIPE).communicate()
El modificador -w hace que el archivo se sobrescriba, pero de forma molesta deja un nombre, por ejemplo, "myfile.xml ~" que probablemente quiera eliminar. Los otros interruptores están ahí para obtener el formato correcto (para mí).
PS xmlindent es un formateador de flujo, es decir, puede usarlo de la siguiente manera:
cat myfile.xml | xmlindent > myfile_indented.xml
Por lo tanto, es posible que pueda usarlo en un script de Python sin escribir en un archivo si lo necesita.
Esta solución funcionó para mí sin parches de mono o dejando de usar minidom:
from xml.dom.ext import PrettyPrint
from StringIO import StringIO
def toprettyxml_fixed (node, encoding=''utf-8''):
tmpStream = StringIO()
PrettyPrint(node, stream=tmpStream, encoding=encoding)
return tmpStream.getvalue()
Esto se puede hacer con toxml (), usando expresiones regulares para arreglar las cosas.
>>> from xml.dom.minidom import Document
>>> import re
>>> doc = Document()
>>> root = doc.createElement(''root'')
>>> _ = doc.appendChild(root)
>>> main = doc.createElement(''Text'')
>>> _ = root.appendChild(main)
>>> text = doc.createTextNode(''Some text here'')
>>> _ = main.appendChild(text)
>>> out = doc.toxml()
>>> niceOut = re.sub(r''><'', r''>/n<'', re.sub(r''(<//.*?>)'', r''/1/n'', out))
>>> print niceOut
<?xml version="1.0" ?>
<root>
<Text>Some text here</Text>
</root>
La forma más sencilla de hacerlo es usar prettyxml y eliminar / n y / t dentro de las etiquetas. De esa manera, mantendrá su sangría como lo requirió en su ejemplo.
xml_output = doc.toprettyxml() nojunkintags = re.sub(''>(/n|/t)</'', '''', xml_output) print nojunkintags