Script de Python para eliminar todos los comentarios del archivo XML

Estoy tratando de crear un script de python que tomará un documento XML y eliminará todos los bloques de comentarios.

Intenté algo como:

tree = ElementTree()
tree.parse(file)
commentElements = tree.findall('//comment()')

for element in commentElements:
    element.parentNode.remove(element)

Hacer esto produce un error extraño de python: "KeyError: '()'

Sé que hay formas de editar fácilmente el archivo usando otros métodos (como sed), pero tengo que hacerlo en un script de python.

preguntado el 03 de mayo de 12 a las 18:05

¿Podría agregar un pequeño documento XML de ejemplo? -

'//comment()' no parece ser un formato de ruta de búsqueda válido y está causando KeyError. ¿Puede incluir esa muestra XML y ampliar el patrón que está tratando de capturar? -

comment() es una prueba de nodo XPath que no es compatible con ElementTree. Tratar lxml, que tiene soporte completo para XPath 1.0. -

lxml también implementa la interfaz etree, AFAIK -

4 Respuestas

comment() es una prueba de nodo XPath que no es compatible con ElementTree.

Puede usar el comment() con lxml. Esta biblioteca es bastante similar a ElementTree y tiene soporte completo para XPath 1.0.

Así es como puede eliminar comentarios con lxml:

from lxml import etree

XML = """<root>
  <!-- COMMENT 1 -->
  <x>TEXT 1</x>
  <y>TEXT 2 <!-- COMMENT 2 --></y>
</root>"""

tree = etree.fromstring(XML)

comments = tree.xpath('//comment()')

for c in comments:
    p = c.getparent()
    p.remove(c)

print etree.tostring(tree)

Salida:

<root>
  <x>TEXT 1</x>
  <y>TEXT 2 </y>
</root>

contestado el 04 de mayo de 12 a las 10:05

Usa strip_tags() de lxml.etree

from lxml import etree
XML = """<root>
  <!-- COMMENT 1 -->
  <x>TEXT 1</x>
  <y>TEXT 2 <!-- COMMENT 2 --></y>
  </root>"""

tree = etree.fromstring(XML)
print etree.tostring(tree)
etree.strip_tags(tree,etree.Comment)
print etree.tostring(tree)

Salida:

<root>
<!-- COMMENT 1 -->
<x>TEXT 1</x>
<y>TEXT 2 <!-- COMMENT 2 --></y>
</root>
<root>

<x>TEXT 1</x>
<y>TEXT 2 </y>
</root>

Respondido 29 ago 13, 18:08

Lo mismo que

https://stackoverflow.com/a/3317008/1458574

from lxml import etree
import sys

XML = open(sys.argv[1]).read()
parser =  etree.XMLParser(remove_comments=True)
tree= etree.fromstring(XML, parser = parser)
print etree.tostring(tree)

contestado el 23 de mayo de 17 a las 13:05

remove_comments=True funciona bien, pero no se usa en la respuesta vinculada. Entonces, ¿por qué dices que es "lo mismo"? - mzjn

Esta es la solución que implementé usando minidom:

 def removeCommentNodes(self):
        for tag in self.dom.getElementsByTagName("*"):
            for n in tag.childNodes:
                if n.nodeType is dom.Node.COMMENT_NODE:
                    n.parentNode.removeChild(n)

En la práctica, primero recupero todas las etiquetas en el xml, luego, para cada etiqueta, busco nodos de comentarios y, si los encuentro, los elimino. (self.dom es una referencia al xml analizado)

Respondido 06 Oct 12, 13:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.