因此,我用ElementTree创建了一个新的子元素,其中新节点的文本应为dict值,如果对应值的dict键等于同一父Node中另一个XML节点的文本。
<ns0:scaleType xmlns:ns0="http://someURL.com/">
<scales>
<scale>
<names>
<name id="0">abc</name>
<name id="1" />
</names>
<alternativeExportValues>
</alternativeExportValues>
</scale>
<scale>
<names>
<name id="0">def</name>
<name id="1" />
</names>
<alternativeExportValues>
</alternativeExportValues>
</scale>
</scales>
</ns0:scaleType>
name;value
abc;10012
def;20025
import xml.etree.ElementTree as ET
import csv
csvData = []
with open('myCSV.csv', 'r', encoding="utf8") as f:
reader = csv.reader(f, delimiter=";")
for row in reader:
csvData.append({'name': row[0], 'value': row[1]})
tree = ET.parse('myXml.xml')
root = tree.getroot()
def my_Function():
for p in csvData:
for name in root.findall(".//name[@id='0']"):
text = name.text
if p['name'] == text:
value = p['value']
return value
my_Function()
for elem in root.iter('alternativeExportValues'):
newNode = ET.SubElement(elem, 'alternativeExportValue')
newNode.text =
tree.write("myNewXML.xml", encoding="utf-8")
<ns0:scaleType xmlns:ns0="http://someURL.com/">
<scales>
<scale>
<names>
<name id="0">abc</name>
<name id="1" />
</names>
<alternativeExportValues>
<alternativeExportValue>10012</alternativeExportValue>
</alternativeExportValues>
</scale>
<scale>
<names>
<name id="0">def</name>
<name id="1" />
</names>
<alternativeExportValues>
<alternativeExportValue>20025</alternativeExportValue>
</alternativeExportValues>
</scale>
</scales>
</ns0:scaleType>
我试图将创建alternativeExportValue
节点的for循环放入中my_Function
,但最终在循环中获得了相同的值newNode.text
或陷入了无限循环。
如您在预期结果中所看到的,如果<name id="0">
dict.value与同一parent中的innerText匹配,我希望dict.value作为新创建的Node的文本<scale>
。
我不确定应该做什么my_Function
,但是请考虑以下逻辑:
scale
元素。alternativeExportValue
用“值”值创建一个新元素。name
元素是否与id
当前“名称”条目匹配。alternativeExportValue
元素。例...
import xml.etree.ElementTree as ET
import csv
with open('myCSV.csv', 'r', encoding="utf8") as csvfile:
tree = ET.parse('myXml.xml')
for row in csv.DictReader(csvfile, delimiter=";"):
name = row.get("name")
new_aev_elem = ET.Element("alternativeExportValue")
new_aev_elem.text = row.get("value")
for scale in tree.findall(".//scale"):
name0 = scale.find("names/name[@id='0']")
if name0.text == name:
aevs_elem = scale.find("alternativeExportValues")
aevs_elem.append(new_aev_elem)
break
tree.write("myNewXML.xml", encoding="utf-8")
这行得通,但效率不高,因为您必须处理要修改scale
的实际scale
元素之前的每个元素。
更糟糕的是,如果删除,break
它将处理scale
XML中的每个元素(对于CSV的每一行!)。
如果可以切换到lxml,则可以使用稍微复杂一点的XPath *,它仅处理scale
需要修改的元素。
from lxml import etree
import csv
with open('myCSV.csv', 'r', encoding="utf8") as csvfile:
tree = etree.parse('myXml.xml')
uc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lc = "abcdefghijklmnopqrstuvwxyz"
for row in csv.DictReader(csvfile, delimiter=";"):
name = row.get("name").lower()
new_aev_elem = etree.Element("alternativeExportValue")
new_aev_elem.text = row.get("value")
aevs_elem = tree.xpath(f".//scale[translate(names/name[@id='0'],'{uc}','{lc}')='{name}']/alternativeExportValues")[0]
aevs_elem.append(new_aev_elem)
tree.write("myNewXML.xml", encoding="utf-8")
* ElementTree中对XPath的支持是有限的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句