我使用Python的iterparse
解析了nessus扫描(.nessus文件)的XML结果。解析失败的意外记录,威尔相似的人已被正确解析。iterparse无法解析字段,而其他类似的字段不正确
XML文件的一般结构是很多类似下面的记录:
<ReportHost>
<ReportItem>
<foo>9.3</foo>
<bar>hello</bar>
</ReportItem>
<ReportItem>
<foo>10.0</foo>
<bar>world</bar>
</ReportHost>
<ReportHost>
...
</ReportHost>
换句话说大量主机(ReportHost
)有很多项目的报告(ReportItem
),和后者具有几个特征(foo
,bar
)。我将考虑为每个产品生成一行,并具有其特征。
解析在文件的中间处(在这种情况下是cvss_base_score
foo
)一个简单的线路发生故障
<cvss_base_score>9.3</cvss_base_score>
同时〜200条类似线已没有问题解析。
相关的一段代码如下 - 它集上下文标记(inReportHost
和inReportEvent
这告诉我,在XML文件中我在的狭窄,并且或者分配或打印一个值,根据上下文)
import xml.etree.cElementTree as ET
inReportHost = False
inReportItem = False
for event, elem in ET.iterparse("test2.nessus", events=("start", "end")):
if event == 'start' and elem.tag == "ReportHost":
inReportHost = True
if event == 'end' and elem.tag == "ReportHost":
inReportHost = False
elem.clear()
if inReportHost:
if event == 'start' and elem.tag == 'ReportItem':
inReportItem = True
cvss = ''
if event == 'start' and inReportItem:
if event == 'start' and elem.tag == 'cvss_base_score':
cvss = elem.text
if event == 'end' and elem.tag == 'ReportItem':
print cvss
inReportItem = False
cvss
有时具有无值(cvss = elem.text
分配后),即使相同的条目已经在文件中properely较早解析。
如果我添加了assignement下面的东西沿着
if cvss is None: cvss = "0"
线则许多进一步的cvss
解析转让他们正确的价值观(和其他一些是没有的)。
当采取<ReportHost>...</reportHost>
导致错误的解析并运行它通过程序 - 它工作正常(即cvss
被分配9.3
按预期)。
我迷失在我犯我代码错误的地方,因为有一大堆类似的记录,一些apre处理正确,有些不 - (某些记录是相同的,而且处理方式不同)。我也找不到任何关于失败记录的特别之处 - 早期和晚期都是一样的。
谢谢你 - 这是真的很有帮助。我更新了XML文件的示例以更好地反映现实(每台主机有几个项目)。我将尝试围绕您的想法构建我的代码,可能有两个循环(一个用于主机,然后用于主机中的项目),但我首先必须清楚地了解迭代的工作原理。 – WoJ
@WoJ:'.iter()'方法是递归的,即无论有多少'ReportItem';所有'cvss_base_score'都可以在他们所属的任何“ReportItem”中找到(或者即使“cvss_base_score”元素在任何“ReportItem”之外)。 – jfs
@ j-f-sebastian:我明白了,但我也需要知道他们属于哪个ReportItem。我试图输出表单行(以XML为例)'host1,foo =“9.3”,bar =“hello”'和'host2,foo =“10.0”,bar =“world”'。现在我已经清楚(从你的例子)如何提取字段,但我需要保持它们在上下文中(将它们链接到它们所属的项目) – WoJ