2009-12-18 19 views
6

Ho un file XML che contiene alcuni dati come dati.Modifica dei testi XML da un file XML usando Python

<?xml version="1.0" encoding="UTF-8" ?> 
- <ParameterData> 
    <CreationInfo date="10/28/2009 03:05:14 PM" user="manoj" /> 
- <ParameterList count="85"> 
- <Parameter name="Spec 2 Included" type="boolean" mode="both"> 
    <Value>n/a</Value> 
    <Result>n/a</Result> 
    </Parameter> 
- <Parameter name="Spec 2 Label" type="string" mode="both"> 
    <Value>n/a</Value> 
    <Result>n/a</Result> 
    </Parameter> 
- <Parameter name="Spec 3 Included" type="boolean" mode="both"> 
    <Value>n/a</Value> 
    <Result>n/a</Result> 
    </Parameter> 
- <Parameter name="Spec 3 Label" type="string" mode="both"> 
    <Value>n/a</Value> 
    <Result>n/a</Result> 
    </Parameter> 
    </ParameterList> 
    </ParameterData> 

Ho un file di testo con le linee come

Spec 2 Included : TRUE 
Spec 2 Label: 19-Flat2-HS3 
Spec 3 Included : FALSE 
Spec 3 Label: 4-1-Bead1-HS3 

Ora voglio modificare i testi XML; I, E. Voglio sostituire il campo (n/a) con i valori corrispondenti dal file di testo. come voglio il file assomiglia

<?xml version="1.0" encoding="UTF-8" ?> 
- <ParameterData> 
    <CreationInfo date="10/28/2009 03:05:14 PM" user="manoj" /> 
- <ParameterList count="85"> 
- <Parameter name="Spec 2 Included" type="boolean" mode="both"> 
    <Value>TRUE</Value> 
    <Result>TRUE</Result> 
    </Parameter> 
- <Parameter name="Spec 2 Label" type="string" mode="both"> 
    <Value>19-Flat2-HS3</Value> 
    <Result>19-Flat2-HS3</Result> 
    </Parameter> 
- <Parameter name="Spec 3 Included" type="boolean" mode="both"> 
    <Value>FALSE</Value> 
    <Result>FALSE</Result> 
    </Parameter> 
- <Parameter name="Spec 3 Label" type="string" mode="both"> 
    <Value>4-1-Bead1-HS3</Value> 
    <Result>4-1-Bead1-HS3</Result> 
    </Parameter> 
    </ParameterList> 
    </ParameterData> 

Sono nuovo di questa codifica Python-XML. Non ho idea di come modificare i campi di testo in un file XML. Sto cercando di utilizzare il modulo elementtree.ElementTree. ma per leggere le righe nel file XML ed estrarre gli attributi Non so quali moduli debbano essere importati.

Per favore aiuto.

Grazie e saluti.

+1

Nel gergo XML, le parti che si desidera cambiare sono chiamate "testo". "Attributo" si riferisce a pezzi come 'name =" Spec 2 Label "' o 'mode =" both "'. –

+0

Dopo aver trascorso un po 'di tempo a capire come farlo usando le informazioni di molti dei suggerimenti, ho scritto una soluzione impropria ma efficace qui: https://stackoverflow.com/questions/1591579/how-to-update -modify-a-xml-file-in-python/48087921 # 48087921. Forse aiuta le persone che devono affrontare un compito simile. –

risposta

6

È possibile convertire il testo i dati in dizionario Python da un'espressione regolare

data="""Spec 2 Included : TRUE 
Spec 2 Label: 19-Flat2-HS3 
Spec 3 Included : FALSE 
Spec 3 Label: 4-1-Bead1-HS3""" 

#data=open("data.txt").read() 

import re 

data=dict(re.findall('(Spec \d+ (?:Included|Label))\s*:\s*(\S+)',data)) 

data sarà il seguente

{'Spec 3 Included': 'FALSE', 'Spec 2 Included': 'TRUE', 'Spec 3 Label': '4-1-Bead1-HS3', 'Spec 2 Label': '19-Flat2-HS3'} 

Quindi è possibile convertire esso utilizzando uno qualsiasi dei vostri parser XML favoriate, ho userà il minidom qui.

from xml.dom import minidom 

dom = minidom.parseString(xml_text) 
params=dom.getElementsByTagName("Parameter") 
for param in params: 
    name=param.getAttribute("name") 
    if name in data: 
     for item in param.getElementsByTagName("*"): # You may change to "Result" or "Value" only 
      item.firstChild.replaceWholeText(data[name]) 

print dom.toxml() 

#write to file 
open("output.xml","wb").write(dom.toxml()) 

Risultati

<?xml version="1.0" ?><ParameterData> 
    <CreationInfo date="10/28/2009 03:05:14 PM" user="manoj"/> 
    <ParameterList count="85"> 
    <Parameter mode="both" name="Spec 2 Included" type="boolean"> 
     <Value>TRUE</Value> 
     <Result>TRUE</Result> 
    </Parameter> 
    <Parameter mode="both" name="Spec 2 Label" type="string"> 
     <Value>19-Flat2-HS3</Value> 
     <Result>19-Flat2-HS3</Result> 
    </Parameter> 
    <Parameter mode="both" name="Spec 3 Included" type="boolean"> 
     <Value>FALSE</Value> 
     <Result>FALSE</Result> 
    </Parameter> 
    <Parameter mode="both" name="Spec 3 Label" type="string"> 
     <Value>4-1-Bead1-HS3</Value> 
     <Result>4-1-Bead1-HS3</Result> 
    </Parameter> 
    </ParameterList> 
</ParameterData> 
+0

Dear Mark, Questo è molto utile. Molte grazie. Sono stalking a un passo stupido. Come posso leggere il file di testo in una stringa come hai fatto all'inizio con il nome (data = "" "" ""). Voglio dire, non sono in grado di convertire il file di testo in un dizionario. Si prega di suggerire. – manoj1123

+0

Ciao, per caricare dal file usa 'data = open (" data.txt "). Read()', invece di 'data =" "" "" "', ho aggiornato anche la mia risposta. – YOU

+0

Gentile Marco, Grazie per il vostro supporto e il vostro tempo. Sono in grado di generare l'output. Come posso usare writexml() per scrivere l'output in un file. Grazie – manoj1123

5

Beh, si potrebbe iniziare con

import xml.etree.ElementTree as ET 
tree = ET.parse("blah.xml") 

Find the elements che si desidera modificare.

Per sostituire il contenuto di un elemento, basta fare

element.text = "TRUE" 

L'istruzione import sopra funziona in Python 2.5 o successiva. Se si dispone di una versione precedente di Python, è necessario installare ElementTree come estensione, quindi l'istruzione import è diversa: import elementtree.ElementTree as ET.

1

Purtroppo, la XPath supportate da ElementTree non è completa. Poiché Python 2.6 include una versione precedente, la ricerca di elementi per attributo (come indicato in here) non funziona. Quindi Python's own documentation dovrebbe essere la vostra prima fermata: xml.etree.ElementTree

import xml.etree.ElementTree as ET 

original = ET.parse("original.xml") 
parameters = original.findall(".//Parameter") 
changes = {} 

# read changes 
with open("changes.txt", "rb") as in_file: 
    for change in in_file: 
     change = change.rstrip()    # remove line endings 
     name, value = change.split(":") 
     changes[name.strip()] = value.strip() # remove whitespaces 

# find paramter element and apply changes 
for parameter in parameters: 
    parameter_name = parameter.get("name") 
    if changes.has_key(parameter_name):     
     value = parameter.find("./Value") 
     value.text = changes[parameter_name] 
     result = parameter.find("./Result") 
     result.text = changes[parameter_name] 

original.write("new.xml") 
+0

Hi wierob, Grazie per il vostro tempo. Poiché sto usando la versione di Python 2.3 a causa di alcuni vincoli wxpython con istruzione aperta potrebbe non funzionare. Così ho fatto il montaggio necessario. In realtà il dizionario delle modifiche mostra solo un elemento. Anche sto ottenendo la riga di errore nome_parametro non è definito. get ("nome") probabilmente non funziona. – manoj1123

1

Ecco come si potrebbe fare utilizzando Amara

from amara import bindery 

doc = bindery.parse(XML) 

def cleanup_for_dict(key, value): 
    return key.strip(), value.strip() 

params = dict((cleanup_for_dict(*line.split(':', 1)) 
       for line in TEXT.splitlines())) 

for param in doc.ParameterData.ParameterList.Parameter: 
    if param.name in params: 
     param.Value = params[param.name] 
     param.Result = params[param.name] 

doc.xml_write()