2010-03-10 52 views
9

属性给出与minidom命名

<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"/> 

我如何与NAME =“frame.len”现场马上不通过每一个标签迭代和检查属性查找元素?

+0

要补充这个问题,xml是300mb。上次我尝试解析它时,内存不足。任何关于更好的萨克斯风格库的建议? – xster 2010-03-10 07:28:02

+0

好吧,'xml.dom.minidom'是一个需要将整个文档读入内存的DOM解析器。不是因为它不够好,而是因为这是DOM解析器所做的。所以我不知道你的意思是“更好的萨克斯风格的图书馆”。 'xml.sax'是Python附带的标准SAX解析器有什么不好? – 2010-03-10 08:23:28

+0

5000个数据包(300mb)后,试图加载xml使我的电脑崩溃。在这300MB的数据中,我只需要大约10kb分布在整个文档中。是否有一种比lxml更为高效的遍历xml的方法和比sax更简单的库? – xster 2010-03-11 04:04:43

回答

13

我不认为你可以。

从父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始终是标记内的第一个属性。

2

你没有 - DOM API,设计有点差(通过W3C,而不是Python!)没有这样的搜索功能来为你做迭代。要么接受循环(不是通过,通常每标签,但通过所有标签名称),或升级到更丰富的接口,如BeautifulSouplxml

0

哇,那个正则表达式太可怕了!截至2016年,每DOMElement有一个.getAttribute()方法,使事情变得更容易,但你仍然需要遍历元素。

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