#python #xml #xml-parsing #elementtree
#питон #xml #xml-синтаксический анализ #элементтри
Вопрос:
Я вообще не знаком с xml-файлами, но пытаюсь разобрать это:
lt;?xml version="1.0" encoding="ISO-8859-1"?gt; lt;modelinggt; lt;generatorgt; lt;i name="subversion" type="string"gt;(build Dec 07 2018 23:19:03) complex parallel lt;/igt; lt;i name="platform" type="string"gt;LinuxIFC lt;/igt; lt;i name="date" type="string"gt;2019 07 11 lt;/igt; lt;i name="time" type="string"gt;11:56:12 lt;/igt; lt;/generatorgt; lt;incargt; lt;i type="int" name="ISTART"gt; 0lt;/igt; lt;i type="string" name="PREC"gt;accuratelt;/igt; lt;i type="int" name="ISPIN"gt; 2lt;/igt; lt;i type="int" name="NELMDL"gt; -8lt;/igt; lt;i type="int" name="IBRION"gt; 2lt;/igt; lt;i name="EDIFF"gt; 0.00001000lt;/igt; lt;i name="EDIFFG"gt; -0.01000000lt;/igt; lt;i type="int" name="NSW"gt; 200lt;/igt; lt;i type="int" name="ISIF"gt; 2lt;/igt; lt;i type="int" name="ISYM"gt; 2lt;/igt; lt;i name="ENCUT"gt; 750.00000000lt;/igt; lt;i name="POTIM"gt; 0.30000000lt;/igt; lt;/incargt;
до сих пор мне удавалось писать код,чтобы получить Elements
как:
#!/usr/bin/env python import xml.etree.ElementTree as ET tree = ET.parse("vasprun.xml") root = tree.getroot() for child in root: print({x for x in root.findall(child.tag)})
который выдает результат в виде:
{lt;Element 'generator' at 0x7f342220ca90gt;} {lt;Element 'incar' at 0x7f342220cd10gt;}
Я пытаюсь получить файл из incar
as:
IStart=0 Prec=accurate
Кто-нибудь может помочь мне получить это?
Комментарии:
1.
[{n.get("name"): n.text.strip() for n in node} for node in root]
Ответ №1:
Нижеприведенные работы (XPath)
import xml.etree.ElementTree as ET xml = '''lt;?xml version="1.0" encoding="UTF-8"?gt; lt;modelinggt; lt;generatorgt; lt;i name="subversion" type="string"gt;(build Dec 07 2018 23:19:03) complex parallellt;/igt; lt;i name="platform" type="string"gt;LinuxIFClt;/igt; lt;i name="date" type="string"gt;2019 07 11lt;/igt; lt;i name="time" type="string"gt;11:56:12lt;/igt; lt;/generatorgt; lt;incargt; lt;i type="int" name="ISTART"gt;0lt;/igt; lt;i type="string" name="PREC"gt;accuratelt;/igt; lt;i type="int" name="ISPIN"gt;2lt;/igt; lt;i type="int" name="NELMDL"gt;-8lt;/igt; lt;i type="int" name="IBRION"gt;2lt;/igt; lt;i name="EDIFF"gt;0.00001000lt;/igt; lt;i name="EDIFFG"gt;-0.01000000lt;/igt; lt;i type="int" name="NSW"gt;200lt;/igt; lt;i type="int" name="ISIF"gt;2lt;/igt; lt;i type="int" name="ISYM"gt;2lt;/igt; lt;i name="ENCUT"gt;750.00000000lt;/igt; lt;i name="POTIM"gt;0.30000000lt;/igt; lt;/incargt; lt;/modelinggt;''' root = ET.fromstring(xml) names = ['ISTART','PREC'] for name in names: i = root.find(f'.//i[@name="{name}"]') print(i.text)
выход
0 accurate
Комментарии:
1. Спасибо, но я не это имел в виду. Я пытаюсь получить все имя=значение внутри incar. Хотя голосовали против.
Ответ №2:
Добавил ваш образец XML в файл после добавления недостающего последнего тега lt;/modelinggt;
Затем:
import xml.etree.ElementTree as ET with open('vasprun.xml') as xml: root = ET.fromstring(xml.read()) for name in ['ISTART', 'PREC']: if (t := root.find(f'.//i[@name="{name}"]')) is not None: print(f'{name}:{t.text.strip()}')
Ответ №3:
Если присутствует тег закрыть моделирование, вы можете использовать XPath для задания.
xpath для получения значения ISTART является :
//incar/*[@name='ISTART']
xpath для получения значения PREC-это :
//incar/*[@name='PREC']
затем :
from lxml import etree xml_doc = """ lt;?xml version="1.0" encoding="ISO-8859-1"?gt; lt;modelinggt; lt;generatorgt; lt;i name="subversion" type="string"gt;(build Dec 07 2018 23:19:03) complex parallel lt;/igt; lt;i name="platform" type="string"gt;LinuxIFC lt;/igt; lt;i name="date" type="string"gt;2019 07 11 lt;/igt; lt;i name="time" type="string"gt;11:56:12 lt;/igt; lt;/generatorgt; lt;incargt; lt;i type="int" name="ISTART"gt; 0lt;/igt; lt;i type="string" name="PREC"gt;accuratelt;/igt; lt;i type="int" name="ISPIN"gt; 2lt;/igt; lt;i type="int" name="NELMDL"gt; -8lt;/igt; lt;i type="int" name="IBRION"gt; 2lt;/igt; lt;i name="EDIFF"gt; 0.00001000lt;/igt; lt;i name="EDIFFG"gt; -0.01000000lt;/igt; lt;i type="int" name="NSW"gt; 200lt;/igt; lt;i type="int" name="ISIF"gt; 2lt;/igt; lt;i type="int" name="ISYM"gt; 2lt;/igt; lt;i name="ENCUT"gt; 750.00000000lt;/igt; lt;i name="POTIM"gt; 0.30000000lt;/igt; lt;/incargt; lt;/modelinggt; """ parser = etree.XMLParser(resolve_entities=False, strip_cdata=False, recover=True, ns_clean=True) xml_tree = etree.fromstring(xml_doc.encode(), parser=parser) istart = xml_tree.xpath('//incar/*[@name="ISTART"]') prec = xml_tree.xpath('//incar/*[@name="PREC"]') print(f'ISTART={int(istart[0].text)}') print(f'Prec={prec[0].text}')