pythonxml解析etree find element X by position

2024-06-16 10:46:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解析下面的xml以提取某些数据,然后根据需要编辑这些数据。在

以下是xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CHECKLIST>
<VULN>
    <STIG_DATA>
        <VULN_ATTRIBUTE>Vuln_Num</VULN_ATTRIBUTE>
        <ATTRIBUTE_DATA>V-38438</ATTRIBUTE_DATA>
    </STIG_DATA>
    <STIG_DATA>
        <VULN_ATTRIBUTE>Rule_Title</VULN_ATTRIBUTE>
        <ATTRIBUTE_DATA>More text.</ATTRIBUTE_DATA>
    </STIG_DATA>
    <STIG_DATA>
        <VULN_ATTRIBUTE>Vuln_Discuss</VULN_ATTRIBUTE>
        <ATTRIBUTE_DATA>Some text here</ATTRIBUTE_DATA>
    </STIG_DATA>
    <STIG_DATA>
        <VULN_ATTRIBUTE>IA_Controls</VULN_ATTRIBUTE>
        <ATTRIBUTE_DATA></ATTRIBUTE_DATA>
    </STIG_DATA>
    <STIG_DATA>
        <VULN_ATTRIBUTE>Rule_Ver</VULN_ATTRIBUTE>
        <ATTRIBUTE_DATA>Gen000000</ATTRIBUTE_DATA>
    </STIG_DATA>
    <STATUS>NotAFinding</STATUS>
    <FINDING_DETAILS></FINDING_DETAILS>
    <COMMENTS></COMMENTS>        
    <SEVERITY_OVERRIDE></SEVERITY_OVERRIDE>
    <SEVERITY_JUSTIFICATION></SEVERITY_JUSTIFICATION>
</VULN>

我希望从中提取的数据是状态、注释和紧跟在VULN_属性后面的属性数据,它与==Rule\u Ver匹配。所以在这个例子中。在

我应该得到以下信息: Gen000000 NotAFinding None

到目前为止,我可以很容易地获得状态和注释,但无法确定属性_数据部分。我可以找到第一个索引(Vuln_Num),然后尝试添加一个索引,但这会出现“list index out out range”错误。在

这就是我现在所处的地方。在

^{pr2}$

这将产生以下输出: GEN:[V-38438] Status:[NotAFinding] Comments: None

我想要: GEN:[Gen000000] Status:[NotAFinding] Comments: None

因此,最终目标是能够解析数百个这样的代码,并根据需要编辑comments字段。我不认为一旦我找到了合适的元素,编辑部分就不会那么难了。在

从逻辑上讲,我认为有两种方法可以做到这一点。或者转到属性_DATA[5]并获取文本,或者找到VULN_ATTRIBUTE==Rule\u,然后获取下一个属性数据。在

我试过这样做:

DataTag = curTag.find(".//STIG_DATA//ATTRIBUTE_DATA")[5] and数据标签[5].text`

都给我IndexError: list index out of range

我看到lxml已经通过'uid和xpath得到了\u元素,但是我不能向这个系统添加模块,所以它对我来说是etree。在

提前谢谢。在


Tags: 数据textnone编辑data属性attributexml
1条回答
网友
1楼 · 发布于 2024-06-16 10:46:58

可以通过位置找到元素,但是使用了不正确的XPath语法。以下任一行都应该有效:

DataTag = curTag.find("./STIG_DATA[5]/ATTRIBUTE_DATA")    # Note: 5, not 4
DataTag = curTag.findall("./STIG_DATA/ATTRIBUTE_DATA")[4] # Note: 4, not 5

但是,我强烈建议不要使用它。不能保证STIG_DATARule_Ver实例始终是第五项。在

如果您可以更改为lxml,那么这就可以了:

^{pr2}$

由于不能使用lxml,因此必须手动迭代STIG_DATA元素,如下所示:

def GetData(curTag):
    for stig in curTag.findall('STIG_DATA'):
        if stig.find('VULN_ATTRIBUTE').text == 'Rule_Ver':
            return stig.find('ATTRIBUTE_DATA')

以下是添加了错误检查的完整程序GetData()

import xml.etree.ElementTree as ET
doc = ET.parse('test.ckl')
root=doc.getroot()

TagList = doc.findall("./VULN")

def GetData(curTag):
    for stig in curTag.findall('STIG_DATA'):
        vuln = stig.find('VULN_ATTRIBUTE')
        if vuln is not None and vuln.text == 'Rule_Ver':
            data = stig.find('ATTRIBUTE_DATA')
            return data

for curTag in TagList:
    StatusTag = curTag.find("STATUS")
    CommentTag = curTag.find("COMMENTS")
    DataTag = GetData(curTag)
    print "GEN:[%s] Status:[%s] Comments: %s" %( DataTag.text, StatusTag.text, CommentTag.text)

参考文献:

相关问题 更多 >