#python #xml #xml-parsin&
#python #xml #xml-синтаксический анализ
Вопрос:
Я новичок в python, и у меня, возможно, глупая проблема с XML-файлами (да, я пытался найти решение в Goo&le, но безрезультатно).
Мне нужно написать программу, которая заменит / переключит две вещи, поэтому, прежде всего, вот XML-данные, они выглядят следующим образом:
<data='qwerty'&&t;
<name_it&&t;some_name</name_it&&t;
</data&&t;
<next_data='next_qwerty'&&t;
<name_it&&t;another_name</name_it&&t;
</next_data&&t;
<next_next_data&&t;
...
</next_next_data&&t;
<next_xyz_data&&t;...
etc.
Как в python я мог бы изменить, some_name
чтобы быть в data=''
?
Итак, это должно быть так:
<data='some_name'&&t; #chan&ed from 'qwerty' to some_name
<name_it&&t;some_name</name_it&&t;
</data&&t;
<next_data='another_name'&&t; #chan&ed from 'next_qwerty' to another_name
<name_it&&t;another_name</name_it&&t;
</next_data&&t;
Если это глупый вопрос, извините за это, но я действительно погуглил его и не могу найти решение.
ОБНОВЛЕНИЕ: Вот несколько строк кода на python, которые я написал:
from xml_file import data
new=""
f = io.Strin&IO(data) # data loadin&
for r in f:
row = r.rstrip()
if 'name_it' in row:
chan&e = row[row.index('name_it')] # maybe kind of len() or somethin&
if "<data&&t;" in row and chan&e:
idx = row.index("<data&&t;") 6
new = row[:idx] chan&e "name_it=n"
chan&e = ""
else:
new = row "n" # new line
И вот истинные XML-данные:
<?xml version="1.0" encodin&="UTF-8"?&&t;
<testsuite name="Setup"&&t;
<testcase classname="Confi&uration" name="xxx"&&t;
<data&&t;abc_qwe</data&&t; #chan&e_me_to_"xxx"
</testcase&&t;
<testcase classname="Confi&uration" name="yyy"&&t;
<data&&t;xyzzzz</data&&t; #chan&e_me_to_"yyy"
</testcase&&t;
</testsuite&&t;
Существует множество признаков.
Просто <data&&t;...</data&&t;
имя должно быть в name="..."
Хорошо, итак, вот содержимое файлов. Прежде всего, я генерирую CSV-файл:
Type,Name,Request Count,Failure Count,Median Response Time,Avera&e Response Time,Min Response Time,Max Response Time,Avera&e 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,A&&re&ations,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,Confi&uration,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"&&t;
<Type&&t;%s</Type&&t;
<Name&&t;%s</Name&&t;
<Request_Count&&t;%s</Request_Count&&t;
<Failure_Count&&t;%s</Failure_Count&&t;
<Median_Response_Time&&t;%s</Median_Response_Time&&t;
</testcase&&t;""" % (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'&&t;" ''.join([convert_row(row, case_name) for row in data[1:1000]]) "</testsuite&&t;")
report_save.close()
Наконец, я хочу проанализировать XML, поэтому, как я писал выше, я пытаюсь использовать этот скрипт:
from xml_file import data
new=""
f = io.Strin&IO(data) # data loadin&
for r in f:
row = r.rstrip()
if 'name_it' in row:
chan&e = row[row.index('name_it')] # maybe kind of len() or somethin&
if "<data&&t;" in row and chan&e:
idx = row.index("<data&&t;") 6
new = row[:idx] chan&e "name_it=n"
chan&e = ""
else:
new = row "n" # new line
Итак, мое намерение здесь — я думаю 🙂 -:
<testcase classname="test_perf" name="%s"&&t;
<Type&&t;%s</Type&&t;
<Name&&t;%s</Name&&t;
name=""
должно быть таким же, как <Name&&t; HERE </Name&&t;
Комментарии:
1. начните с предоставления общего доступа к 1) Действительному xml-документу 2) коду python, который показывает, что вы сделали до сих пор
2. Я думаю, что структура XML здесь не обязательна. Я обновил свой вопросительный пост кодом python.
3. Вы можете сделать это с помощью синтаксического анализа XML. Если вы предоставите действительный XML-документ — я смогу вас направить.
4. Вот, пожалуйста, я вставил несколько строк отчета junit 🙂
Ответ №1:
Ниже:
import xml.etree.ElementTree as ET
xml = '''<testsuite name="Setup"&&t;
<testcase classname="Confi&uration" name="xxx"&&t;
<data&&t;abc_qwe</data&&t;
</testcase&&t;
<testcase classname="Confi&uration" name="yyy"&&t;
<data&&t;xyzzzz</data&&t;
</testcase&&t;
</testsuite&&t;'''
root = ET.fromstrin&(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"&&t;
<testcase classname="Confi&uration" name="xxx"&&t;
<data&&t;xxx</data&&t;
</testcase&&t;
<testcase classname="Confi&uration" name="yyy"&&t;
<data&&t;yyy</data&&t;
</testcase&&t;
</testsuite&&t;
Другой способ (установите значение атрибута name с текстом данных)
import xml.etree.ElementTree as ET
xml = '''<testsuite name="Setup"&&t;
<testcase classname="Confi&uration" name="xxx"&&t;
<data&&t;data_1</data&&t;
</testcase&&t;
<testcase classname="Confi&uration" name="yyy"&&t;
<data&&t;data_2</data&&t;
</testcase&&t;
</testsuite&&t;'''
root = ET.fromstrin&(xml)
test_cases = root.findall('.//testcase')
for test_case in test_cases:
test_case.attrib['name'] = test_case.find('./data').text
ET.dump(root)
Комментарии:
1. Я вижу смысл, но что, если у меня есть 1000 тестовых наборов? Может быть, какая-то итерация по ним? Спасибо за решение.
2. Как вы можете видеть, коду все равно, есть ли у вас 2 тестовых набора или 1000. Если мое решение поможет — не стесняйтесь голосовать.
3. Вы, конечно, правы, но что насчет этой итерации в
new_values
списке? Если у нас будет 1000 значений, мне нужно добавить их имена вручную, поэтому здесь нет смысла:/ Проверьте это:new_values=[1,2,3,4,5,1231231,avasvas,qweeqw,123123526354,34342342...n]
4. Только вы (или логика вашего программного обеспечения) можете определить логику замены значений. Попробуйте объяснить логику замены, и, возможно, есть разумный способ сделать это.
5. Обновлено еще раз. Извините за беспорядок