使用minidom查找具有属性的元素

10 投票
3 回答
20142 浏览
提问于 2025-04-15 20:14

给定

<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 个回答

0

哇,那个正则表达式真是太糟糕了!从2016年开始,每个DOMElement都有一个.getAttribute()的方法,这样做事情会简单一些,但你还是得一个一个地遍历这些元素。

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

你不能这样做——这个DOM API,设计得有点糟糕(这不是Python的问题,是w3c的问题!),没有提供这样的搜索功能来帮你自动遍历。你要么接受需要手动循环(不是遍历每一个标签,而是遍历所有具有特定标签名的标签),要么可以选择更强大的工具,比如BeautifulSouplxml

16

我觉得你可能做不到。

从父级 element 开始,你需要

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

针对你3月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 始终是标签内的第一个属性。

撰写回答