Найти элемент с атрибутом с минидом - PullRequest
9 голосов
/ 10 марта 2010

Дано

<field name="frame.time_delta_displayed" showname="Time delta from previous displayed frame: 0.000008000 seconds" size="0" pos="0" show="0.000008000"/>
<field name="frame.time_relative" showname="Time since reference or first frame: 0.000008000 seconds" size="0" pos="0" show="0.000008000"/>
<field name="frame.number" showname="Frame Number: 2" size="0" pos="0" show="2"/>
<field name="frame.pkt_len" showname="Packet Length: 1506 bytes" hide="yes" size="0" pos="0" show="1506"/>
<field name="frame.len" showname="Frame Length: 1506 bytes" size="0" pos="0" show="1506"/>
<field name="frame.cap_len" showname="Capture Length: 1506 bytes" size="0" pos="0" show="1506"/>
<field name="frame.marked" showname="Frame is marked: False" size="0" pos="0" show="0"/>
<field name="frame.protocols" showname="Protocols in frame: eth:ip:tcp:http:data" size="0" pos="0" show="eth:ip:tcp:http:data"/>

Как получить поле с именем = "frame.len" сразу, не просматривая каждый тег и не проверяя атрибуты?

Ответы [ 3 ]

14 голосов
/ 10 марта 2010

Не думаю, что ты можешь.

От родителя element вам необходимо

for subelement in element.GetElementsByTagName("field"):
    if subelement.hasAttribute("frame.len"):
        do_something()

Реакция на ваш комментарий от 11 марта, если структура ваших документов стабильна и не содержит неприятных сюрпризов (например, угловые скобкивнутри атрибутов), вы можете попробовать немыслимое и использовать регулярное выражение.Это не рекомендуемая практика, но она может сработать и будет намного проще, чем фактический анализ файла.Я признаю, что иногда делал это сам.Еще не ослеп.

Так что в вашем случае вы могли бы (при условии, что тег <field> не занимает несколько строк):

xmlfile = open("myfile.xml")
for line in xmlfile:
    match = re.search(r'<field\s+name="frame.len"\s+([^>]+)/>', line):
    if match:
        result = match.group(1)
        do_something(result)

Если тег <field> может занимать несколько строк, вы можете попробовать загрузить весь файл в виде простого текста в память и затем отсканировать его на совпадения:

filedump = open("myfile.xml").read()
for match in re.finditer(r'<field\s+name="frame.len"\s+([^>]+)/>', filedump):
    result = match.group(1)
    do_something(result)

В обоих случаях result будет содержать атрибутыкроме frame.len.Регулярное выражение предполагает, что frame.len всегда является первым атрибутом внутри тега.

2 голосов
/ 10 марта 2010

У вас нет - DOM API , несколько неудачно спроектированный (w3c, а не Python! -), не имеет такой функции поиска, чтобы выполнить итерацию за вас. Либо согласитесь с необходимостью выполнить цикл (не через каждый тег в целом, но и через все с заданным именем тега), либо обновите до более насыщенного интерфейса, такого как BeautifulSoup или lxml.

0 голосов
/ 25 июля 2016

Ух ты, это регулярное выражение ужасно! По состоянию на 2016 год для каждого DOMElement существует метод .getAttribute(), который немного облегчает задачу, но вам все равно придется перебирать элементы.

l = []
for e in elements:
    if e.hasAttribute('name') and e.getAttribute('name') == 'field.len':
        l.append(e)
...