Как обновить все вложенные теги XML разными значениями с помощью BeautifulSoup

#python-3.x #xml #beautifulsoup #xml-parsing

#python-3.x #xml #beautifulsoup #xml-синтаксический анализ

Вопрос:

допустим, это мой XML

 <sky class="new">
<list name="school">
<p>63</p>
<p>62</p>
<p>61</p>
</list>
</sky>
  

И это мои значения в списке.

 value = [51,56,87]
  

Теперь мне нужно:

 <sky class="new">
<list name="school">
<p>51</p>
<p>56</p>
<p>87</p>
</list>
</sky>
  

Пока это то, что я сделал:

 for i in soup.find_all('sky', {'class':'new'}):
        k = i.find('list',{'name':'school'})
  

После этого я не понимаю, что делать, не могли бы вы помочь здесь?

ПРАВКА1:

 <sky class="new">
    <list name="alpha">
<item>
    <p unit="kg">63</p>
    <p weight="wg">54</p>
</item>
<item>
    <p unit="kg">57</p>
    <p weight="wg">32</p>
    
</item>
</list>
    </sky>
  

Ответ №1:

Другая версия:

 from bs4 import BeautifulSoup


txt = '''<sky class="new">
<list name="school">
<p>63</p>
<p>62</p>
<p>61</p>
</list>
</sky>'''

soup = BeautifulSoup(txt, 'xml')
values = [51, 56, 87]

for p, new_value in zip(soup.select('sky.new > list[name="school"] > p'), values):
    p.string = str(new_value)

print(soup)
  

С принтами:

 <?xml version="1.0" encoding="utf-8"?>
<sky class="new">
<list name="school">
<p>51</p>
<p>56</p>
<p>87</p>
</list>
</sky>
  

Комментарии:

1. Почему вы оставили <sky class=»new»>, на самом деле у нас есть много таких тегов с разными именами классов, например <sky class=»aplha»>, <sky class =»beta»> и т.д., И я хочу делать это только тогда, когда class =»new».

2. @AkashRathor Что вы можете сделать 'sky.new > list[name="school"] > p' . Смотрите мою правку.

3. На самом деле вместо ‘html parser’ я использовал синтаксический анализатор ‘xml’, я забыл его обновить, и с xml parser он не работает, что мы можем здесь сделать?

4. Наконец-то это сработало и у меня, спасибо за ваши решения и пояснения.

5. @AkashRathor, Тогда ты можешь сделать sky.new > list[name="alpha"] > item > p[unit="kg"]

Ответ №2:

Попробуйте что-то вроде этого:

 targets = soup.select('p')
for target in targets:
    repl = str(value[targets.index(target)])
    target.string.replace_with(repl)

soup
  

Выходной сигнал:

 <html><body><sky class="new">
<list name="school">
<p>51</p>
<p>56</p>
<p>87</p>
</list>
</sky></body></html>