为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 python pandas 数据框架更新和添加 XML 文件中的属性

如何使用 python pandas 数据框架更新和添加 XML 文件中的属性

明月笑刀无情 2023-08-08 17:11:10
我是 XML 新手,有没有有效的方法可以使用 pandas 数据框架匹配文本并更新 XML 文件?这是我的大型 XML 文件的一小部分,它仍然遵循适当的格式。XML 文件(input.xml):<?xml version="1.0" encoding="UTF-8"?><brand by="hhdhdh" date="2014/01/01" name="OOP-112200" Insti="TGA">   <design name="OOP-112200" own="TGA" descri="" sound_db="JJKO">      <sec name="abcd" sound_freq="abcd" c_ty="pv">         <feature number="48">            <tfgt v="0.1466469683747654" y="0.0" units="sec" />         </feature>         <mwan sound_freq="abcd" first_name="g7tty" description="xyz" />      </sec>      <sec name="M_20_K40745170" sound_freq="mhr17:7907527-7907589" tension="SGCGSCGSCGSCGSC" s_c="0">         <feature number="5748">            <tfgt v="0.1466469683747654" y="0.0" units="sec" />         </feature>         <mwan sound_freq="mhr17:7907527-7907589" first_name="g7tty" description="xyz">        </mwan>      </sec>      <sec name="M_20_K40745171" sound_freq="mhr17:7907528-7907599" tension="SGCGSCGSCGSHHGSC" s_c="0">         <feature number="5748">            <tfgt v="0.1466469683747654" y="0.0" units="sec" />         </feature>         <mwan sound_freq="mhr17:7907527-7907589" first_name="gtftty" description="xyz">            <xyz abc="trt" id="abc" />            <per fre="acc" value="abc" />            <per fre="xyz" value="abc" />            <per fre="yy" value="abc" />         </mwan>      </sec>      #file continue....   </design></brand>数据框(用作输入):                name       Volum_5mb      Volum_40mb     Volum_70mb1     M_20_K40745170         89.00           44.00         77.002     M_20_K40745171         77.00           65.00         94.00我想匹配name列中的元素,如果匹配,则使用列的其余部分来创建新属性,如下所示。例如,如果 elements ( M_20_K40745170) fromdf['name']存在/匹配,则分别在输出文件中使用以下行更新相应的节点。<per fre="Volum_5mb" value="89.00"/><per fre="Volum_40mb" value="44.00"/><per fre="Volum_70mb" value="77.00"/>
查看完整描述

1 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

你可以学习xml并且因为主要问题与但是xpath无关。pandasxml


您可以使用更复杂的方法xpath来查找具有名称M_20_K40745170和子节点的节点mwam,您必须在其中搜索pre和更新它(甚至添加新的pre)


node = root.find('./design/sec[@name="M_20_K40745170"]//mwan')

你可以用df.iterrows()这个


for index, row in df.iterrows():

    node = root.find('./design/sec[@name="{}"]//mwan'.format(row['name']))

稍后您可以per使用以下命令进行搜索"Volum_5mb"


item = node.find('./per[@fre="Volum_5mb"]')

并创建新的和/或更新值


if not item:  # if item is None:

    item = ET.SubElement(node, 'per')

    item.set('fre', "Volum_5mb")


item.set('value', str(row['Volum_5mb']))

你可以使用列表['Volum_5mb', 'Volum_40mb', 'Volum_70mb']来做到这一点


for fre in ['Volum_5mb', 'Volum_40mb', 'Volum_70mb']:


    item = node.find('./per[@fre="{}"]'.format(fre))

    #print(fre, item)


    if not item:

        item = ET.SubElement(node, 'per')

        item.set('fre', fre)


    item.set('value', str(row[fre]))

直接在代码中包含示例数据的最小工作代码,但您应该从文件中读取它们。


text = '''                name       Volum_5mb      Volum_40mb     Volum_70mb

1     M_20_K40745170         89.00           44.00         77.00

2     M_20_K40745171         77.00           65.00         94.00'''


xml = '''<?xml version="1.0" encoding="UTF-8"?>

<brand by="hhdhdh" date="2014/01/01" name="OOP-112200" Insti="TGA">

   <design name="OOP-112200" own="TGA" descri="" sound_db="JJKO">

      <sec name="abcd" sound_freq="abcd" c_ty="pv">

         <feature number="48">

            <tfgt v="0.1466469683747654" y="0.0" units="sec" />

         </feature>

         <mwan sound_freq="abcd" first_name="g7tty" description="xyz" />

      </sec>

      <sec name="M_20_K40745170" sound_freq="mhr17:7907527-7907589" tension="SGCGSCGSCGSCGSC" s_c="0">

         <feature number="5748">

            <tfgt v="0.1466469683747654" y="0.0" units="sec" />

         </feature>

         <mwan sound_freq="mhr17:7907527-7907589" first_name="g7tty" description="xyz">

         </mwan>

      </sec>

      <sec name="M_20_K40745171" sound_freq="mhr17:7907528-7907599" tension="SGCGSCGSCGSHHGSC" s_c="0">

         <feature number="5748">

            <tfgt v="0.1466469683747654" y="0.0" units="sec" />

         </feature>

         <mwan sound_freq="mhr17:7907527-7907589" first_name="gtftty" description="xyz">

            <xyz abc="trt" id="abc" />

            <per fre="acc" value="abc" />

            <per fre="xyz" value="abc" />

            <per fre="yy" value="abc" />

         </mwan>

      </sec>

   </design>

</brand>'''


import pandas as pd

import io

import xml.etree.ElementTree as ET


#df = pd.read_csv('input.csv')

df = pd.read_csv(io.StringIO(text), sep='\s+')

#print(df)


#tree = ET.('input.xml')

#root = tree.getroot()

root = ET.fromstring(xml)

tree = ET.ElementTree(root)


for index, row in df.iterrows():

    node = root.find('./design/sec[@name="{}"]//mwan'.format(row['name']))

    

    for fre in ['Volum_5mb', 'Volum_40mb', 'Volum_70mb']:


        item = node.find('./per[@fre="{}"]'.format(fre))

        #print('item:', fre, '=', item)


        if not item:

            #print('new', item, fre)

            item = ET.SubElement(node, 'per')

            #item.tail = '\n         '  # to pretty print

            item.set('fre', fre)


        item.set('value', str(row[fre]))


    #print(ET.tostring(node).decode())

    

#---

    

print( ET.tostring(root) )

#tree.write('output.xml')


查看完整回答
反对 回复 2023-08-08
  • 1 回答
  • 0 关注
  • 114 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信