You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python通过属性名解析XML字符串获取对应值

从CSV中的XML字符串提取属性值(Python)

我正在使用Python,需要从CSV文件读取的XML字符串中提取特定值。示例XML字符串如下:

<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
    <System>
        <Provider Name='Microsoft-Windows' Guid='{aaaa-ss-www-qqq-qeqweqwe}'/>
        <EventID>4771</EventID>
        <Version>0</Version>
        <Level>0</Level>
        <Task>1000</Task>
        <Opcode>0</Opcode>
        <Keywords>0x9110</Keywords>
        <TimeCreated SystemTime='2022-01-01T00:00:00.000000Z'/>
        <EventRecordID>123123123</EventRecordID>
        <Correlation/>
        <Execution ProcessID='2' ThreadID='11'/>
        <Channel>Security</Channel>
        <Computer>pcname</Computer>
        <Security/>
    </System>
    <EventData>
        <Data Name='TargetUserName'>user</Data>
        <Data Name='TargetSid'>S-1-5-21-123123-321312-123132-31212</Data>
        <Data Name='ServiceName'>service/dom</Data>
        <Data Name='TicketOptions'>0x123123</Data>
        <Data Name='Status'>0xq</Data>
        <Data Name='PreAuthType'>0</Data>
        <Data Name='IpAddress'>::ffff:8.8.8.8</Data>
        <Data Name='IpPort'>123321</Data>
        <Data Name='CertIssuerName'></Data>
        <Data Name='CertSerialNumber'></Data>
        <Data Name='CertThumbprint'></Data>
    </EventData>
</Event>

我已编写了一段可通过属性路径获取部分值的代码:

import os, csv
import xml.etree.ElementTree as ET

def cls():
    os.system('cls' if os.name=='nt' else 'clear')
cls()

raw = open('C:/tmp2/data.csv', 'r')
reader = csv.reader(raw)
line_number = 1
for i, row in enumerate(reader):
    if i == line_number:
        break

tree = ET.fromstring(''.join(row))
EventID = [literal.text for literal in tree.findall('.//{http://schemas.microsoft.com/win/2004/08/events/event}System/{http://schemas.microsoft.com/win/2004/08/events/event}EventID')]
TimeCreated = [literal.text for literal in tree.findall('.//{http://schemas.microsoft.com/win/2004/08/events/event}System/{http://schemas.microsoft.com/win/2004/08/events/event}TimeCreated[@Name=&quot;SystemTime&quot;]')]
TargetUserName = [literal.text for literal in tree.findall('.//{http://schemas.microsoft.com/win/2004/08/events/event}EventData/{http://schemas.microsoft.com/win/2004/08/events/event}Data[@Name=&quot;TargetUserName&quot;]')]
ServiceName = [literal.text for literal in tree.findall('.//{http://schemas.microsoft.com/win/2004/08/events/event}EventData/{http://schemas.microsoft.com/win/2004/08/events/event}Data[@Name=&quot;ServiceName&quot;]')]

print ('EVENT:',''.join(EventID))
print ('TimeCreated:',''.join(TimeCreated))
print ('TargetUserName:',''.join(TargetUserName))
print ('ServiceName:', ''.join(ServiceName))

请问如何通过属性名获取对应的属性值,例如获取类似EventID这类目标的相关值?


解决方案

1. 简化命名空间处理

XML带有固定命名空间,直接写完整URL会冗余,先定义命名空间映射:

ns = {'evt': 'http://schemas.microsoft.com/win/2004/08/events/event'}

之后所有XPath查询用evt:前缀代替长串命名空间URL,代码更简洁。

2. 两种提取场景的处理

  • 提取元素文本(如EventID):用find()定位元素后,直接取.text属性(这类值在标签内部)。
  • 提取元素属性值(如TimeCreated的SystemTime):定位元素后,用.get('属性名')方法获取对应属性值。

3. 优化后的完整代码

import os, csv
import xml.etree.ElementTree as ET

def cls():
    os.system('cls' if os.name=='nt' else 'clear')
cls()

# 定义命名空间映射
ns = {'evt': 'http://schemas.microsoft.com/win/2004/08/events/event'}

# 读取CSV中的目标行XML字符串
with open('C:/tmp2/data.csv', 'r') as raw:
    reader = csv.reader(raw)
    line_number = 1
    target_row = None
    for i, row in enumerate(reader):
        if i == line_number:
            target_row = ''.join(row)
            break

# 解析XML
tree = ET.fromstring(target_row)

# 提取元素文本
event_id = tree.find('.//evt:System/evt:EventID', ns).text
target_user = tree.find('.//evt:EventData/evt:Data[@Name="TargetUserName"]', ns).text
service_name = tree.find('.//evt:EventData/evt:Data[@Name="ServiceName"]', ns).text

# 提取属性值
time_created = tree.find('.//evt:System/evt:TimeCreated', ns).get('SystemTime')
provider_name = tree.find('.//evt:System/evt:Provider', ns).get('Name')
process_id = tree.find('.//evt:System/evt:Execution', ns).get('ProcessID')

# 输出结果
print(f'EVENT: {event_id}')
print(f'TimeCreated: {time_created}')
print(f'TargetUserName: {target_user}')
print(f'ServiceName: {service_name}')
print(f'Provider Name: {provider_name}')
print(f'Process ID: {process_id}')

说明

  • 用with open()代替直接open(),自动处理文件关闭,更安全。
  • find()返回单个匹配元素(适用于唯一目标),比findall()更高效,无需处理列表。
  • EventData下的Data元素通过[@Name="属性名"]的XPath条件定位,直接提取对应文本。

内容的提问来源于stack exchange,提问作者Peter Asp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:31:24