如何通过 python 替换 XML 节点
How to replace an XML node via python
我是 python 的新人,我有一个 - 也许 - XML 文件的愚蠢问题(是的,我已经尝试 google 解决方案但没有结果)。
我必须编写一个程序来 replace/switch 两件事,所以首先,这是 XML 数据,它看起来像这样:
<data='qwerty'>
<name_it>some_name</name_it>
</data>
<next_data='next_qwerty'>
<name_it>another_name</name_it>
</next_data>
<next_next_data>
...
</next_next_data>
<next_xyz_data>...
etc.
如何在 python 中将 some_name
更改为 data=''
?
所以应该是这样的:
<data='some_name'> #changed from 'qwerty' to some_name
<name_it>some_name</name_it>
</data>
<next_data='another_name'> #changed from 'next_qwerty' to another_name
<name_it>another_name</name_it>
</next_data>
如果这是一个愚蠢的问题,对此表示抱歉,但我确实 google 解决了这个问题,但我找不到解决方案。
更新:
这是我写的几行 python 代码:
from xml_file import data
new=""
f = io.StringIO(data) # data loading
for r in f:
row = r.rstrip()
if 'name_it' in row:
change = row[row.index('name_it')] # maybe kind of len() or something
if "<data>" in row and change:
idx = row.index("<data>") + 6
new += row[:idx] + change + "name_it=\n"
change = ""
else:
new += row + "\n" # new line
这是真的 XML 数据:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>abc_qwe</data> #change_me_to_"xxx"
</testcase>
<testcase classname="Configuration" name="yyy">
<data>xyzzzz</data> #change_me_to_"yyy"
</testcase>
</testsuite>
有很多迹象。
只是 <data>...</data>
名字应该在 name="..."
好了,文件内容就到这里。
首先,我正在生成 CSV 文件:
Type,Name,Request Count,Failure Count,Median Response Time,Average Response Time,Min Response Time,Max Response Time,Average Content Size,Requests/s,Failures/s,50%,66%,75%,80%,90%,95%,98%,99%,99.9%,99.99%,99.999%,100%
POST,---ON START---LOGIN,33,0,2023.709774017334,2037.008133801547,2023.709774017334,2058.631658554077,6587.515151515152,0.24352046353820625,0.0,2000,2000,2000,2000,2100,2100,2100,2100,2100,2100,2100,2100
GET,Aggregations,15,0,4,5.305735270182292,3.652334213256836,11.571884155273438,6174.2,0.11069111979009376,0.0,4,5,7,7,9,12,12,12,12,12,12,12
GET,Alarms,5,0,5,4.584074020385742,3.754138946533203,5.759000778198242,6173.8,0.03689703993003125,0.0,5,5,5,6,6,6,6,6,6,6,6,6
GET,Analysis Templates,16,0,7,7.806003093719482,3.8690567016601562,13.520479202270508,6174.625,0.11807052777610001,0.0,9,11,11,11,12,14,14,14,14,14,14,14
GET,Boiler Efficiency,15,0,6,6.464735666910808,3.6771297454833984,15.489578247070312,6174.2,0.11069111979009376,0.0,6,6,8,11,11,15,15,15,15,15,15,15
GET,Configuration,14,0,5,6.087354251316616,3.6630630493164062,12.647390365600586,6174.428571428572,0.1033117118040875,0.0,5,6,8,11,11,13,13,13,13,13,13,13
然后,我想把它改成 XML:
import _csv
from locust_script import methods_count
with open('locust_stats.csv') as f, open('locus_statistics.csv', 'w') as out:
for line in f:
if not line.isspace():
print(line.strip())
out.write(line)
stats = open('locus_statistics.csv')
csv_f = _csv.reader(stats)
data = []
for row in csv_f:
data.append(row)
def convert_row(row, methods):
case_name = methods[0]
del methods[0]
return """
<testcase classname="test_perf" name="%s">
<Type>%s</Type>
<Name>%s</Name>
<Request_Count>%s</Request_Count>
<Failure_Count>%s</Failure_Count>
<Median_Response_Time>%s</Median_Response_Time>
</testcase>""" % (case_name, row[0], row[1], row[2], row[3], row[4])
report_save = open('parsed.xml', 'w')
case_name = methods_count()
report_save.write("<testsuite name='performance'>"+''.join([convert_row(row, case_name) for row in data[1:1000]])+"</testsuite>")
report_save.close()
最后,我想解析XML,所以正如我上面写的,我尝试使用这种脚本:
from xml_file import data
new=""
f = io.StringIO(data) # data loading
for r in f:
row = r.rstrip()
if 'name_it' in row:
change = row[row.index('name_it')] # maybe kind of len() or something
if "<data>" in row and change:
idx = row.index("<data>") + 6
new += row[:idx] + change + "name_it=\n"
change = ""
else:
new += row + "\n" # new line
所以我的意图在这里 - 我想 :) -:
<testcase classname="test_perf" name="%s">
<Type>%s</Type>
<Name>%s</Name>
name=""
应与 <Name> HERE </Name>
相同
以下:
import xml.etree.ElementTree as ET
xml = '''<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>abc_qwe</data>
</testcase>
<testcase classname="Configuration" name="yyy">
<data>xyzzzz</data>
</testcase>
</testsuite>'''
root = ET.fromstring(xml)
test_cases = root.findall('.//testcase')
for test_case in test_cases:
test_case.find('./data').text = test_case.attrib['name']
ET.dump(root)
输出
<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>xxx</data>
</testcase>
<testcase classname="Configuration" name="yyy">
<data>yyy</data>
</testcase>
</testsuite>
另一种方式(用data的文本设置name属性的值)
import xml.etree.ElementTree as ET
xml = '''<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>data_1</data>
</testcase>
<testcase classname="Configuration" name="yyy">
<data>data_2</data>
</testcase>
</testsuite>'''
root = ET.fromstring(xml)
test_cases = root.findall('.//testcase')
for test_case in test_cases:
test_case.attrib['name'] = test_case.find('./data').text
ET.dump(root)
我是 python 的新人,我有一个 - 也许 - XML 文件的愚蠢问题(是的,我已经尝试 google 解决方案但没有结果)。
我必须编写一个程序来 replace/switch 两件事,所以首先,这是 XML 数据,它看起来像这样:
<data='qwerty'>
<name_it>some_name</name_it>
</data>
<next_data='next_qwerty'>
<name_it>another_name</name_it>
</next_data>
<next_next_data>
...
</next_next_data>
<next_xyz_data>...
etc.
如何在 python 中将 some_name
更改为 data=''
?
所以应该是这样的:
<data='some_name'> #changed from 'qwerty' to some_name
<name_it>some_name</name_it>
</data>
<next_data='another_name'> #changed from 'next_qwerty' to another_name
<name_it>another_name</name_it>
</next_data>
如果这是一个愚蠢的问题,对此表示抱歉,但我确实 google 解决了这个问题,但我找不到解决方案。
更新: 这是我写的几行 python 代码:
from xml_file import data
new=""
f = io.StringIO(data) # data loading
for r in f:
row = r.rstrip()
if 'name_it' in row:
change = row[row.index('name_it')] # maybe kind of len() or something
if "<data>" in row and change:
idx = row.index("<data>") + 6
new += row[:idx] + change + "name_it=\n"
change = ""
else:
new += row + "\n" # new line
这是真的 XML 数据:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>abc_qwe</data> #change_me_to_"xxx"
</testcase>
<testcase classname="Configuration" name="yyy">
<data>xyzzzz</data> #change_me_to_"yyy"
</testcase>
</testsuite>
有很多迹象。
只是 <data>...</data>
名字应该在 name="..."
好了,文件内容就到这里。 首先,我正在生成 CSV 文件:
Type,Name,Request Count,Failure Count,Median Response Time,Average Response Time,Min Response Time,Max Response Time,Average Content Size,Requests/s,Failures/s,50%,66%,75%,80%,90%,95%,98%,99%,99.9%,99.99%,99.999%,100%
POST,---ON START---LOGIN,33,0,2023.709774017334,2037.008133801547,2023.709774017334,2058.631658554077,6587.515151515152,0.24352046353820625,0.0,2000,2000,2000,2000,2100,2100,2100,2100,2100,2100,2100,2100
GET,Aggregations,15,0,4,5.305735270182292,3.652334213256836,11.571884155273438,6174.2,0.11069111979009376,0.0,4,5,7,7,9,12,12,12,12,12,12,12
GET,Alarms,5,0,5,4.584074020385742,3.754138946533203,5.759000778198242,6173.8,0.03689703993003125,0.0,5,5,5,6,6,6,6,6,6,6,6,6
GET,Analysis Templates,16,0,7,7.806003093719482,3.8690567016601562,13.520479202270508,6174.625,0.11807052777610001,0.0,9,11,11,11,12,14,14,14,14,14,14,14
GET,Boiler Efficiency,15,0,6,6.464735666910808,3.6771297454833984,15.489578247070312,6174.2,0.11069111979009376,0.0,6,6,8,11,11,15,15,15,15,15,15,15
GET,Configuration,14,0,5,6.087354251316616,3.6630630493164062,12.647390365600586,6174.428571428572,0.1033117118040875,0.0,5,6,8,11,11,13,13,13,13,13,13,13
然后,我想把它改成 XML:
import _csv
from locust_script import methods_count
with open('locust_stats.csv') as f, open('locus_statistics.csv', 'w') as out:
for line in f:
if not line.isspace():
print(line.strip())
out.write(line)
stats = open('locus_statistics.csv')
csv_f = _csv.reader(stats)
data = []
for row in csv_f:
data.append(row)
def convert_row(row, methods):
case_name = methods[0]
del methods[0]
return """
<testcase classname="test_perf" name="%s">
<Type>%s</Type>
<Name>%s</Name>
<Request_Count>%s</Request_Count>
<Failure_Count>%s</Failure_Count>
<Median_Response_Time>%s</Median_Response_Time>
</testcase>""" % (case_name, row[0], row[1], row[2], row[3], row[4])
report_save = open('parsed.xml', 'w')
case_name = methods_count()
report_save.write("<testsuite name='performance'>"+''.join([convert_row(row, case_name) for row in data[1:1000]])+"</testsuite>")
report_save.close()
最后,我想解析XML,所以正如我上面写的,我尝试使用这种脚本:
from xml_file import data
new=""
f = io.StringIO(data) # data loading
for r in f:
row = r.rstrip()
if 'name_it' in row:
change = row[row.index('name_it')] # maybe kind of len() or something
if "<data>" in row and change:
idx = row.index("<data>") + 6
new += row[:idx] + change + "name_it=\n"
change = ""
else:
new += row + "\n" # new line
所以我的意图在这里 - 我想 :) -:
<testcase classname="test_perf" name="%s">
<Type>%s</Type>
<Name>%s</Name>
name=""
应与 <Name> HERE </Name>
以下:
import xml.etree.ElementTree as ET
xml = '''<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>abc_qwe</data>
</testcase>
<testcase classname="Configuration" name="yyy">
<data>xyzzzz</data>
</testcase>
</testsuite>'''
root = ET.fromstring(xml)
test_cases = root.findall('.//testcase')
for test_case in test_cases:
test_case.find('./data').text = test_case.attrib['name']
ET.dump(root)
输出
<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>xxx</data>
</testcase>
<testcase classname="Configuration" name="yyy">
<data>yyy</data>
</testcase>
</testsuite>
另一种方式(用data的文本设置name属性的值)
import xml.etree.ElementTree as ET
xml = '''<testsuite name="Setup">
<testcase classname="Configuration" name="xxx">
<data>data_1</data>
</testcase>
<testcase classname="Configuration" name="yyy">
<data>data_2</data>
</testcase>
</testsuite>'''
root = ET.fromstring(xml)
test_cases = root.findall('.//testcase')
for test_case in test_cases:
test_case.attrib['name'] = test_case.find('./data').text
ET.dump(root)