Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果dict.key等于同一父节点中的其他XML节点,则将ET.SubElement.text设置为dict.value_Python_Xml_Elementtree - Fatal编程技术网

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

Python 如果dict.key等于同一父节点中的其他XML节点,则将ET.SubElement.text设置为dict.value,python,xml,elementtree,Python,Xml,Elementtree,因此,我正在使用ElementTree创建一个新的子元素,其中新节点的文本应该是dict值,如果相应值的dict键等于同一父节点中另一个XML节点的文本 XML示例: Python代码现在: 预期成果: abc 10012 def 20025 我试图将创建alternativeExportValue节点的for循环放入my\u函数中,但最终在newNode.text中得到了相同的值,或者陷入了无休止的循环中。 正如您在预期结果中所看到的,如果在同一个父代码< >代码> > < p> >

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

XML示例: Python代码现在: 预期成果:

abc
10012
def
20025

我试图将创建
alternativeExportValue
节点的for循环放入
my\u函数中,但最终在
newNode.text中得到了相同的值,或者陷入了无休止的循环中。



正如您在预期结果中所看到的,如果在同一个父代码< >代码> >

< p> >,我希望DIATE值作为新创建的节点的文本,如果它与
<代码> <代码>内文匹配。
  • 读取/处理CSV数据。(您已经这样做了,但是考虑一下。这将使用第一行的键将值映射到DICT。)
  • 处理每个
    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的每一行!)

如果可以切换到,则可以使用稍微复杂一点的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")

*in-ElementTree有限。

谢谢@Daniel Haley。我使用
My_函数的想法是在
//name[@id=“0”]
中查找匹配键的值。我尝试切换到lxml,但是
aevs\u elem=tree.xpath(f)。//scale[names/name[@id='0']='{name}']/alternativeExportValues”)[0]
返回
索引器:列表索引超出范围。这意味着xPath不存在。@Alecbalec-您也切换到DictReader了吗?如果不是,您可能正在处理CSV的第一行,而XPath由于
name[@id='0']='name'
而失败。如果您不想切换到DictReader,您可以跳过CSV的第一行或使用try/except。如果您切换到DictReader,您的CSV或XML中一定有不同的内容,因为我用您的问题进行了测试,没有发现任何错误。首先,非常感谢!第一个问题是读取csv文件时的编码。在for循环中,我运行了
print(row)
来查看输出,它返回了
'\ufeffname':
而不是
name:
。将编码更改为“utf-8-sig”
,事情看起来好多了。我取消了代码注释并添加了一个
print(get.('value'))
查看.csv文件中的哪一行代码实际中断。快速查看后,很明显,
xPath
是区分大小写的,这就是它返回
索引器的原因:列表索引超出范围
@Alecbalec-啊,是的xPath肯定区分大小写。在XP中强制值为大写或小写是一种痛苦ath 1.0(这是lxml支持的),但我将更新我的lxml答案,使其不区分大小写。是的,幸运的是,只有几行字符在原始XML文件中是小写的,而在csv文件中是大写的。再次感谢。
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>
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")
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")