Как мне найти тег в XML-файле, используя ElementTree, где у меня есть определенный тег «Parent» с определенным значением?(Python) - PullRequest
0 голосов
/ 25 января 2019

Я только начал изучать Python и должен написать программу, которая анализирует XML-файлы.Я должен найти определенный тег с именем OrganisationReference в 2 разных файлах и вернуть его.На самом деле существует несколько тегов с этим именем, но только один, тот, который я пытаюсь вернуть, имеет тег OrganisationType со значением DEALER в качестве родительского тега (не совсем уверен, является ли термин правильным).Я пытался использовать ElementTree для этого.Вот код:

    import xml.etree.ElementTree as ET

    tree1 = ET.parse('Master1.xml')
    root1 = tree1.getroot()

    tree2 = ET.parse('Master2.xml')
    root2 = tree2.getroot()

    for OrganisationReference in root1.findall("./Organisation/OrganisationId/[@OrganisationType='DEALER']/OrganisationReference"):
        print(OrganisationReference.attrib)

    for OrganisationReference in root2.findall("./Organisation/OrganisationId/[@OrganisationType='DEALER']/OrganisationReference"):
        print(OrganisationReference.attrib)

Но это ничего не возвращает (также без ошибок).Кто-нибудь может мне помочь?

Мой файл выглядит так:

  <MessageOrganisationCount>a</MessageOrganisationCount>
  <MessageVehicleCount>x</MessageVehicleCount>
  <MessageCreditLineCount>y</MessageCreditLineCount>
  <MessagePlanCount>z</MessagePlanCount>
  <OrganisationData>
      <Organisation>
          <OrganisationId>
              <OrganisationType>DEALER</OrganisationType>
              <OrganisationReference>WHATINEED</OrganisationReference>
          </OrganisationId>
          <OrganisationName>XYZ.</OrganisationName>
 ....

Из-за того, что OrganisationReference появляется еще несколько раз в этом файле с различным текстом между start и endtag, я хочучтобы получить именно тот, который вы видите в строке 9: он имеет OrganisationId в качестве родительского тега, а DEALER также является дочерним тегом OrganisationId.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Вы были очень близки с вашей первоначальной попыткой.Вам просто нужно внести пару изменений в ваш xpath и небольшое изменение в вашем питоне.

Первая часть вашего xpath начинается с ./Organization.Поскольку вы делаете xpath от root, он ожидает, что Organization будет дочерним.Это не;это потомок.

Попробуйте изменить ./Organization на .//Organization.(// это сокращение от /descendant-or-self::node()/. Для получения дополнительной информации см. Здесь. )

Вторая проблема связана с OrganisationId/[@OrganisationType='DEALER'].Это неверный путь xpath./ должен быть удален между OrganisationId и предикатом .

Кроме того, @ - это сокращенный синтаксис для оси attribute:: , а OrganisationType - это элемент, а не атрибут.

Попробуйте изменить OrganisationId/[@OrganisationType='DEALER'] на OrganisationId[OrganisationType='DEALER'].

Проблема с питоном связана с print(OrganisationReference.attrib).OrganisationReference не имеет никаких атрибутов;просто текст.

Попробуйте изменить print(OrganisationReference.attrib) на print(OrganisationReference.text).

Вот пример использования только одного XML-файла для демонстрационных целей ...

XML Input (Master1.xml; с добавлением элемента doc для придания ему правильной формы)

<doc>
    <MessageOrganisationCount>a</MessageOrganisationCount>
    <MessageVehicleCount>x</MessageVehicleCount>
    <MessageCreditLineCount>y</MessageCreditLineCount>
    <MessagePlanCount>z</MessagePlanCount>
    <OrganisationData>
        <Organisation>
            <OrganisationId>
                <OrganisationType>DEALER</OrganisationType>
                <OrganisationReference>WHATINEED</OrganisationReference>
            </OrganisationId>
            <OrganisationName>XYZ.</OrganisationName>
        </Organisation>
    </OrganisationData>
</doc>

Python

import xml.etree.ElementTree as ET

tree1 = ET.parse('Master1.xml')
root1 = tree1.getroot()

for OrganisationReference in root1.findall(".//Organisation/OrganisationId[OrganisationType='DEALER']/OrganisationReference"):
    print(OrganisationReference.text)

НапечатаноВывод

WHATINEED

Также обратите внимание, что вам не нужно вообще использовать getroot().Вы можете использовать findall() прямо на дереве ...

import xml.etree.ElementTree as ET

tree1 = ET.parse('Master1.xml')

for OrganisationReference in tree1.findall(".//Organisation/OrganisationId[OrganisationType='DEALER']/OrganisationReference"):
    print(OrganisationReference.text)
0 голосов
/ 25 января 2019

Вы можете использовать вложенный цикл for, чтобы сделать это.Сначала вы проверяете, является ли текст OrganisationType ДИЛЕРОМ, а затем получаете текст OrganisationReference, который вам нужен.

Если вы хотите узнать больше о разборе XML с помощью Python, я настоятельно рекомендую документация библиотеки XMLtree.

import xml.etree.ElementTree as ET

tree1 = ET.parse('Master1.xml')
root1 = tree1.getroot()

tree2 = ET.parse('Master2.xml')
root2 = tree2.getroot()

#Find the parent Dealer
for element in root1.findall('./Organisation/OrganisationId'):
    if element[0].text == "DEALER":
         print(element[1].text)

Это работает, если первым тегом в вашем OrganisationId является OrganisationType :)

...