#python #xml #file
#python #xml #файл
Вопрос:
Я хочу заменить определенную строку в файле значением переменной:
В моем файле есть эти 2 строки:
<CtrlSum>10</CtrlSum>
<sum>45</sum>
Я хочу найти значение «10» и заменить его на «45».
Я пробовал что-то подобное:
with open(path,'r ') as f:
lst=f.readlines()
for j in lst:
if'sum' in j:
Somme = j.split('>')[1].split('<')[0]
print(Somme)
for i in lst:
if 'CtrlSum' in i:
Ctrl = i.split('>')[1].split('<')[0]
print (Ctrl)
f.writelines(f.replace(Ctrl,Somme))
Но у меня есть эта ошибка:
f.writelines(f.replace(Ctrl, Somme)) Ошибка атрибута: объект ‘_io.TextIOWrapper’ не имеет атрибута ‘replace’
Что не так и как я могу это исправить?
Комментарии:
1.
f
это файл. Вы можете вызывать только.replace()
строку (т. Е. результат.read()
)2. Обычно я создаю другой файл, копирую в него измененное содержимое, а затем переименовываю его, чтобы переопределить оригинал
3. что вы пытаетесь сделать? заменить какую строку на что? — чего вы планируете достичь с помощью этих разделений?
4. я хочу заменить значение между < > в «CtrlSum» значением «Sum» @DevCl9
5. Вы спрашиваете, как проанализировать файл XML или HTML?
Ответ №1:
Вы можете просто сделать что-то вроде этого:
import re
with open('a.txt','r') as f:
text_value = f.read()
sum_val = sum(map(int, re.findall(r'<sum>(d )</sum>', text_value)))
with open('a.txt','w') as f:
f.write(re.sub(r'<CtrlSum>(. )</CtrlSum>', f'<CtrlSum>{sum_val}</CtrlSum>', text_value))
Нет необходимости в readlines()
or writelines()
или любом цикле. Просто прочитайте весь текст с помощью .read()
-> обработать его -> write()
.
Комментарии:
1. Да, но без readlines() я не могу перебирать свои файлы, чтобы искать разные варианты того, что я ищу: в данном случае значение между <> после строки «CtrlSum» @DevCl9
2. WDYM? не могли бы вы поделиться образцом входного файла и желаемым результатом? (если этот код не вырезает ее)
3. представьте, что в моем файле есть эти 2 строки: <CtrlSum>10</CtrlSum> <sum>45</sum> я хочу найти значение «10» и заменить его на «45» , извините, если это не очень понятно! @DevCl9
4. Да! но это добавляет весь текст после первого, есть ли способ перезаписать его?
5. Да, но если «Сумма» встречается несколько раз, есть ли какой-нибудь способ их добавить?@ DevCl9
Ответ №2:
Функция replace() может использоваться только для строки. Ваш f — это не строка, это сам файл. Вам нужно вызвать f.read(), чтобы получить содержимое файла в виде строки, и вызвать replace() для этого.
РЕДАКТИРОВАТЬ: Проверьте эту ссылку, в ней объясняются различные методы записи в файлы 🙂
Ответ №3:
Используйте синтаксический анализ XML
import xml.etree.ElementTree as ET
xml = '''<r><CtrlSum>10</CtrlSum>
<sum>45</sum></r>'''
root = ET.fromstring(xml)
root.find('.//CtrlSum').text = root.find('.//sum').text
ET.dump(root)
вывод
<r>
<CtrlSum>45</CtrlSum>
<sum>45</sum>
</r>
Комментарии:
1. Но будет ли это решение работать, когда в файле XML будет много элементов, дочерних элементов и дочерних элементов? или это просто работает с этим примером? @balderman
2. Попробуйте это на своем XML и оставьте отзыв
Ответ №4:
Решение XSLT 3.0:
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="CtrlSum/text()">
<xsl:value-of select="//sum"/>
</xsl:template>
</xsl:transform>
(Использование XSLT 1.0 также возможно, просто немного более подробное).