通过索引查找和替换XML属性-Python [英] Find and Replace XML Attributes by Indexing - Python

查看:57
本文介绍了通过索引查找和替换XML属性-Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试基于索引来查找XML属性并将其替换为新值.如果我将属性值本身硬编码到我的find/replace函数中,则可以替换属性值,但是我需要通过索引来实现,特别是对于前两个列出的带有"text"的属性.< foo_1>的两个值和< foo_2>元素.以下是XML,以及我正在使用的脚本以及要添加到XML的新值和所需的输出:

I am attempting to find and replace XML attributes with new values based on indexing. I can replace the attribute values if I hard code the attribute values themselves into my find/replace function, but I need to do so via indexing, specifically for the first two listed attributes with "text" values for both the <foo_1> and <foo_2> elements. Below is the XML, along with the script I am using and the new values to be added to the XML and desired output:

XML("foo_bar.xml")

The XML ("foo_bar.xml")

<?xml version="1.0" encoding="UTF-8"?>
<Overlay>
    <foo_1>
        <bar key="value">text_1</bar>
        <bar key="value">text_2</bar>
        <bar key="value">text_3</bar>
    </foo_1>
    <foo_2>
        <bar key="value">text_4</bar>
        <bar key="value">text_5</bar>
        <bar key="value">text_6</bar>
    </foo_2>
</Overlay>

脚本

import lxml.etree as ET
xml = ET.parse("C:\\Users\\mdl518\\Desktop\\bar_foo.xml")
tree=xml.getroot()

new_val_1 = float(100/202)
new_val_2 = float(200/500)
new_val_3 = float(4/44)
new_val_4 = float(4/1000)

# Find and replace first and second "bar" subelement attribute values for each "foo" parent element
for elem in tree.getiterator():
    if elem.text:
        elem.text=elem.text.replace(text_1,new_val_1)
    if elem.text:
        elem.text=elem.text.replace(text_2,new_val_2)
    if elem.text:
        elem.text=elem.text.replace(text_4,new_val_3)
    if elem.text:
        elem.text=elem.text.replace(text_5,new_val_4)
    print(elem.text)

所需结果

<?xml version="1.0" encoding="UTF-8"?>
<Overlay
    <foo_1>
        <bar key="value">new_val_1</bar>
        <bar key="value">new_val_2</bar>
        <bar key="value">text</bar>
    </foo_1>
    <foo_2>
        <bar key="value">new_val_3</bar>
        <bar key="value">new_val_4</bar>
        <bar key="value">text</bar>
    </foo_2>
</Overlay>

是否有一种方便的方法来索引子元素属性值并将其替换为所需的值(即"new_val_#")并写入XML?非常感谢您的协助!

Is there a convenient way to index the subelement attribute values and replace them with the desired values (i.e. "new_val_#") and write to XML? Any assistance is most appreciated!

推荐答案

在所需值列表和 iterfind 生成器上考虑元素级循环 zip .运行嵌套循环以对齐元素和值的集合.另外,由于每个XML元素都有一个基础文本节点(是否为空),因此无需检查 elem.text .如果整个字符串包含 text ,则只需分配而不是 replace .请注意: zip 在较短的列表上停止逐元素循环:

Consider elementwise loop, zip, on list of your needed values and iterfind generator. Run a nested loop for aligning sets of elements and values. Also there is no need to check if elem.text since every XML element has an underlying text node (empty or not). And if entire string contains text simply assign rather than replace. Do note: zip stops elementwise looping on shorter list:

# LIST OF VALUES
new_vals = [float(100/202), float(200/500), float(4/44), float(4/1000)]

# SUBLIST OF VALUES BY 2 (ADJUST 2 FOR ANY OTHER NUMBER)
sub_new_vals = [new_vals[i:i+2]  for i in range(0, len(new_vals), 2)]

for nvs, el in zip(sub_new_vals, tree.iterfind('./*')):
    # Find and replace first and second attribute values
    for nv, elem in zip(nvs, el.iterfind('./*')):
        #elem.attrib["key"] = str(round(nv, 3))       # UPDATE ATTRIBUTE VALUE
        elem.text = str(round(nv, 3))                 # UPDATE ELEMENT TEXT
        print(elem.text)
                          
output = ET.tostring(tree, 
                     encoding="UTF-8",
                     method="xml", 
                     xml_declaration=True, 
                     pretty_print=True)
  
print(output.decode("utf-8"))

输出

0.495
0.4
0.091
0.004
<?xml version='1.0' encoding='UTF-8'?>
<Overlay>
    <foo_1>
        <bar key="value">0.495</bar>
        <bar key="value">0.4</bar>
        <bar key="value">text_3</bar>
    </foo_1>
    <foo_2>
        <bar key="value">0.091</bar>
        <bar key="value">0.004</bar>
        <bar key="value">text_6</bar>
    </foo_2>
</Overlay>

这篇关于通过索引查找和替换XML属性-Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆