python - 如果 dict.key 等于同一父级中的其他 XML 节点,则将 ET.SubElement.text 设置为 dict.value

标签 python xml elementtree

因此,我使用 ElementTree 创建一个新的子元素,其中新节点的文本应该是一个字典值,如果相应值的字典键等于同一父节点中另一个 XML 节点的文本。

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>

CSV 示例:

name;value
abc;10012
def;20025

现在的Python代码:

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 中获得相同的值或陷入无限循环。

正如您在预期结果中看到的,我希望 dict.value 作为新创建节点的文本(如果它与
<name id="0"> 匹配)同一父级中的innerText <scale> .

最佳答案

我不太确定 my_Function 应该做什么,但请考虑以下逻辑:

  • 读取/处理 CSV 数据。 (您已经这样做了,但请考虑使用 DictReader。这将使用第一行中的键将值映射到字典。)
  • 处理每个scale元素。
  • 使用“value”值创建一个新的 alternativeExportValue 元素。
  • 检查 id 属性值为“0”的 name 元素是否与当前“name”条目匹配。
  • 如果是,请附加新的 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,它将处理 XML 中的每个 scale 元素(对于 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")

*XPath support ElementTree 中的内容是有限的。

关于python - 如果 dict.key 等于同一父级中的其他 XML 节点,则将 ET.SubElement.text 设置为 dict.value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59290381/

相关文章:

python - 如何从 Google App Engine 上的 URL 将文件存储在 Google Storage 上?

python - Django聚合

sql-server - 如何在不知道树是否已经存在的情况下将元素插入到 xml 列中?

python - 为什么在这种情况下要追加 list.extend ?

python - 导入SWIG+python模块报错"undefined symbol"

xml - 运行多个 phpunit.xml 文件?

java - 使用 XPath 搜索和检索 XML 中的属性

python - 从子节点之后的 XML 节点中提取文本

python - 将 XML 解析为 Dataframe 时生成重复值(填充?)

Python3 - 尝试获取数据属性值时,XPath 查询不会从站点返回整个列表