проанализируйте xml-файл с помощью python3

#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}')