Как искать несколько атрибутов, используя xpath в ElementTree - PullRequest
0 голосов
/ 05 апреля 2020

Я хочу выделить следующие значения из файла XML (https://digitallibrary.un.org/search?ln=en&p=A / RES / 72/266 & f = & rm = & ln = en & sf = & so = d & rg = 50 & c = United + Nations + Digital + Библиотека + Система & of = xm & fti = 0 & fti = 0 ).

<collection>
  <record>
    ...
    <datafield tag="993" ind1="2" ind2=" ">
      <subfield code="a">A/C.5/72/L.22</subfield> # Value to isolate: A/C.5/72/L.22
    </datafield>
    <datafield tag="993" ind1="3" ind2=" ">
      <subfield code="a">A/72/682</subfield> # Value to isolate: A/72/682
    </datafield>
    <datafield tag="993" ind1="4" ind2=" ">
      <subfield code="a">A/72/PV.76</subfield> # Value to isolate: A/72/PV.76
    </datafield>
    ...
  </record>
  <record>
    ...
    <datafield tag="993" ind1="2" ind2=" ">
      <subfield code="a">A/C.5/72/L.22</subfield> # Value to isolate: A/C.5/72/L.22
    </datafield>
    <datafield tag="993" ind1="3" ind2=" ">
      <subfield code="a">A/72/682</subfield> # Value to isolate: A/72/682
    </datafield>
  </record>
  ...
</collection>

Код, который я подготовил, кажется, идентифицирует только для каждой записи первый элемент с тегом 993.

for record in root:
  if record.find("{http://www.loc.gov/MARC21/slim}datafield[@tag='993']/{http://www.loc.gov/MARC21/slim}subfield[@code='a']") is not None:
    symbol = record.find("{http://www.loc.gov/MARC21/slim}datafield[@tag='993']/{http://www.loc.gov/MARC21/slim}subfield[@code='a']").text
    print symbol

Есть ли способ l oop для поиска нескольких атрибутов, используя xpath ElementTree? Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Для завершения ответа пользователя3091877, альтернативный параметр XPath:

//*[name()="subfield"][@code="a"][parent::*[@tag="993"]]/text()

РЕДАКТИРОВАТЬ: Это вернет 6 значений (@ tag = 993 и @ ind1 = 3):

//*[name()="subfield"][parent::*[@tag="993" and @ind1="3"]]/text()
0 голосов
/ 05 апреля 2020

Документы показывают, что .find() получает только первый соответствующий подэлемент. Звучит так, как вы хотите .findall().

Мне кажется, что мне подойдет следующее:

import xml.etree.ElementTree as ET
tree = ET.parse(input_file)
root = tree.getroot()

for record in root:
    xpath = "{http://www.loc.gov/MARC21/slim}datafield[@tag='993']/{http://www.loc.gov/MARC21/slim}subfield[@code='a']"
    if record.findall(xpath) is not None:
        for symbol in record.findall(xpath):
            print symbol.text

...