ElementTree найти возвращает «Нет»? - PullRequest
2 голосов
/ 21 марта 2020

Я использую ElementTree с Python для анализа файла XML.

Это пример файла XML, который я пытаюсь проанализировать:

<?xml version="1.0" encoding="UTF-8"?>
<objects fpmi.archive.type="components" framework.version="7.9.8.2018060714" fpmi.version="9.9.8.0" timestamp="Thu Sep 27 15:00:19 CEST 2018">
  <arraylist len="0"/>
<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>10.0;10.0;26.0;14.0</r2dd>
    <str>X123_C61023</str>
    <lc>10.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>X123_X123_C61023</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>[network]premium/aw1/tags/monitors</str>
  </c-c>
</c>

консоль всегда возвращает None.

Мой код:

import xml.etree.ElementTree as ET

mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

for x in myroot.findall('c'):
        p2df=x.find('p2df')
        r2dd=x.find('r2dd')
        print(p2df, r2dd)

Пожалуйста, помогите ..

Ответы [ 2 ]

1 голос
/ 22 марта 2020

спасибо за вашу помощь. но я сделал это и по-другому.:

import xml.etree.ElementTree as ET

mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

interface = myroot.getchildren()[1].getchildren()[0]
print(interface)

r2dd = interface.getchildren()[1]
print(r2dd.text)

str = interface.getchildren()[2]
print(str.text)

Теперь у меня есть следующая проблема, как добавить значения для других элементов в этом xml? я имею в виду следующие элементы, это файл:

<?xml version="1.0" encoding="UTF-8"?>
<objects fpmi.archive.type="components" framework.version="7.9.8.2018060714" fpmi.version="9.9.8.0" timestamp="Thu Sep 27 15:00:19 CEST 2018">
  <arraylist len="0"/>
<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>10.0;10.0;26.0;14.0</r2dd>
    <str>XXY_Y61021</str>
    <lc>10.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>XXY_Y6102_C61021</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>XXXYYYYY</str>
  </c-c>
</c>

<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>60.0;10.0;26.0;14.0</r2dd>
    <str>XXY_Y61022</str>
    <lc>60.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>XXY_Y6102_C61022</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>XXXYYYYY</str>
  </c-c>
</c>

<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>110.0;10.0;26.0;14.0</r2dd>
    <str>XXY_Y61021</str>
    <lc>110.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>XXY_Y6102_C61021</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>XXXYYYYY</str>
  </c-c>
</c>

да, в этом примере отсутствует закрытие для объекта, но на p c у меня есть полный файл

1 голос
/ 21 марта 2020

Element.findall() ищет только элементы с тегом, которые являются прямыми потомками текущего элемента. То же самое происходит с find(), но find() возвращает первое совпадение. Итак, сначала вам нужно перейти к c-comm, чтобы найти элемент p2df, и, поскольку objects является узлом root, вы сначала перейдете к c, затем c-comm, чтобы затем найти объекты. Смотрите ниже фрагмент.

import xml.etree.ElementTree as ET

mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

cNode = myroot.find('c')
for x in cNode.findall('c-comm'):
  p2df=x.find('p2df')
  r2dd=x.find('r2dd')
  print(p2df.text, r2dd.text)

Ваш пример xml не очень хорошо сформирован. Вам нужен закрывающий тег </objects> в конце, чтобы синтаксический анализатор мог прочитать файл.

...