2010-12-17 30 views
11

Actualmente usando Python 2.4.3, y no se les permite actualizarCómo mantener los comentarios al analizar XML usando Python/elementtree

quiero cambiar los valores de un atributo determinado en una o más etiquetas, junto con XML-comentarios en el archivo actualizado.

He conseguido crear un script en Python que toma un archivo XML como argumento, y para cada etiqueta especificada cambia un atributo, como se muestra a continuación

def update(file, state): 
    global Etree 
    try: 
     from elementtree import ElementTree 
     print '*** using ElementTree' 
    except ImportError, e: 
     print '***' 
     print '*** Error: Must install either ElementTree or lxml.' 
     print '***' 
     raise ImportError, 'must install either ElementTree or lxml' 
    #end try 

    doc = Etree.parse(file) 
    root = doc.getroot() 

    for element in root.findall('.//StateManageable'): 
     element.attrib['initialState'] = state 
    #end for 
    doc.write(file) 
#end def 

esto está bien, los atributos "initialState "se actualizan, excepto por el hecho de que mi XML original también contiene muchos comentarios XML, pero se han ido hace mucho tiempo, lo que es malo.

Sospecho que el análisis solo recupera la estructura XML, pero pensé que los comentarios XML eran parte de la estructura. También me doy cuenta de que el formateo "legible por humanos" de mi documento original se ha ido, pero que me he dado cuenta de que es el comportamiento esperado, es necesario formatearlo después usando xmllint --format o XSL.

+3

2.4? Mis condolencias. – delnan

+0

apueste, tuve un momento difícil cuando comencé a crear mis primeros scripts al darme cuenta de que _todas las cosas buenas que encontré eran 2.7 :-) – rhellem

Respuesta

16

Sé que esto es viejo ahora, pero me encontré con esta respuesta anterior sobre cómo retener los comentarios. Frederik's published instructions acerca de cómo poner comentarios en el árbol aún funciona con las versiones actuales de ElementTree, pero hace más de lo que necesita para mi uso, al menos. Envuelve el XML en un elemento, lo cual es indeseable para mí. Tampoco necesito preservar las instrucciones de procesamiento, solo comentarios. Por lo tanto, arreglada abajo de la clase que proporciona en el sitio para esto:

import xml.etree.ElementTree as ET 

class PCParser(ET.XMLTreeBuilder): 

    def __init__(self): 
     ET.XMLTreeBuilder.__init__(self) 
     # assumes ElementTree 1.2.X 
     self._parser.CommentHandler = self.handle_comment 

    def handle_comment(self, data): 
     self._target.start(ET.Comment, {}) 
     self._target.data(data) 
     self._target.end(ET.Comment) 

Para usar esto, cree una instancia de este objeto como un 'analizador' y luego pasa como un parámetro para ElementTree.parse() como esto:

parser = PCParser() 
self.tree = ET.parse(self.templateOut, parser=parser) 

tomo ningún crédito en absoluto por el código, o por el uso de indocumentado elementtree, pero funciona para mí en la preservación únicos comentarios sin afectar a la estructura del documento original. Y tenga en cuenta que cualquier cambio futuro en ElementTree (parece poco probable en este momento después de todos estos años, sin embargo) romperá esto.

+0

Estoy usando 'lxml' para esto y estoy tratando de hacer que funcione. Estoy importando 'de lxml import etree como et'. Creo que puedo reemplazar 'self._parser' con' et' pero no puedo imaginar qué usar en lugar de 'self._target'. ¿Puede usted ayudar? – eoinzy

Cuestiones relacionadas