2009-12-18 70 views
6

我有一個XML文件,其中包含一些給定的數據。使用Python編輯XML文件中的XML文本

<?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> 

我有一個行文本文件作爲

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

現在我想編輯XML文本; I,E。我想用文本文件中的相應值替換字段(n/a) 。 就像我要像

<?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> 

的文件看起來我是新來這個Python的XML編碼。 我沒有關於如何編輯XML文件中的文本字段的想法。 我正在嘗試使用elementtree.ElementTree模塊。 ,但要讀取XML文件中的行,並提取屬性,我不知道哪些模塊需要導入。

請幫助。

感謝和問候。

+1

在XML行話做到這一點,你要更改的部分被稱爲「文本」。 「屬性」是指像「name =」Spec 2標籤「或」mode =「兩者都是」。 – 2009-12-18 05:59:32

+0

花費了相當多的時間,結合幾條建議的信息後,我寫了一個不正確但有效的解決方案:https://stackoverflow.com/questions/1591579/how-to-update -modify-A-XML的文件中的Python/48087921#48087921。也許它有助於面臨類似任務的人們。 – 2018-01-04 02:43:23

回答

6

您可以通過正則表達式的數據文本到Python字典轉換

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將作如下

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

然後你可以使用任何你favoriate XML解析器轉換它,我將在這裏使用minidom。

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()) 

結果

<?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

親愛的馬克, 這是如此有幫助。非常感謝。我被愚蠢地盯住了一步。 如何將文本文件讀入字符串,就像您在名稱開始時所做的那樣(data =「」「」「」)。我的意思是我無法將文本文件轉換爲字典。請建議。 – manoj1123 2009-12-19 06:31:16

+0

嗨,從文件加載使用這個'data = open(「data.txt」)。read()',而不是'data =「」「」「」',我也更新了我的答案。 – YOU 2009-12-19 07:39:02

+0

尊敬的馬克, 感謝您的支持和時間。 我能夠生成輸出。 如何使用writexml()將輸出寫入文件。 謝謝 – manoj1123 2009-12-19 08:57:13

5

嗯,你可以用

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

要修改Find the elements開始。

要替換元素的內容,只是做

element.text = "TRUE" 

import語句以上在Python 2.5或更高版本的作品。如果您有較舊版本的Python,則需要將ElementTree作爲擴展來安裝,然後導入語句是不同的:import elementtree.ElementTree as ET

1

不幸的是,ElementTree中支持的XPath是不完整的。由於Python 2.6包含舊版本,因此按屬性查找元素(如here所述)不起作用。所以Python's own documentation應該是您的第一站: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

嗨wierob, 謝謝你的時間。 因爲我使用python 2.3版本,由於一些wxpython約束與open語句可能無法正常工作。所以我做了必要的編輯。 其實更改字典只顯示一個元素。 另外我得到錯誤行parameter_name沒有定義。 get(「name」)可能不起作用。 – manoj1123 2009-12-19 07:04:35

1

這裏是你如何能使用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()