Заменить определенную строку в файле XML

#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() для этого.

РЕДАКТИРОВАТЬ: Проверьте эту ссылку, в ней объясняются различные методы записи в файлы 🙂

https://pythonexamples.org/python-replace-string-in-file/

Ответ №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 также возможно, просто немного более подробное).