我很难正确地从xml文件中解析元素(请参阅下面的xml片段),并将它们转换为csv。
csv文件包含用于eventType、probableCause、alarmName、shortName (ACAT, AC etc)和longName (ACTangent, ACODE, etc)的列。
与此类似的想法:

目前,我只能让它从警报开始解析信息,但我希望它从一开始就开始。对于每一个日志和警报,我如何在一列中提取家庭longName,而在另一列提取家庭shortName?
如果需要澄清,请告诉我。
XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<faults version="1" xmlns="urn:nortel:namespaces:mcp:faults" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:nortel:namespaces:mcp:faults NortelFaultSchema.xsd ">
<family longName="1OffMsgr" shortName="OOM"/>
<family longName="ACTAGENT" shortName="ACAT">
<logs>
<log>
<eventType>RES</eventType>
<number>1</number>
<severity>INFO</severity>
<descTemplate>
<msg>Accounting is enabled upon this NE.</msg>
</descTemplate>
<note>This log is generated when setting a Session Manager's AM from <none> to a valid AM.</note>
<om>On all instances of this Session Manager, the <NE_Inst>:<AM>:STD:acct OM row in the StdRecordStream group will appear and start counting the recording units sent to the configured AM.
On the configured AM, the <NE_inst>:acct OM rows in RECSTRMCOLL group will appear and start counting the recording units received from this Session Manager's instances.
</om>
</log>
<log>
<eventType>RES</eventType>
<number>2</number>
<severity>ALERT</severity>
<descTemplate>
<msg>Accounting is disabled upon this NE.</msg>
</descTemplate>
<note>This log is generated when setting a Session Manager's AM from a valid AM to <none>.</note>
<action>If you do not intend for the Session Manager to produce accounting records, then no action is required. If you do intend for the Session Manager to produce accounting records, then you should set the Session Manager's AM to a valid AM.</action>
<om>On all instances of this Session Manager, the <NE_Inst>:<AM>:STD:acct OM row in the StdRecordStream group that matched the previous datafilled AM will disappear.
On the previously configured AM, the <NE_inst>:acct OM rows in RECSTRMCOLL group will disappear.
</om>
</log>
</logs>
</family>
<family longName="ACODE" shortName="AC">
<alarms>
<alarm>
<eventType>ADMIN</eventType>
<number>1</number>
<probableCause>INFORMATION_MODIFICATION_DETECTED</probableCause>
<descTemplate>
<msg>Configured data for audiocode server updated: $1</msg>
<param>
<num>1</num>
<description>AudioCode configuration data got updated</description>
<exampleValue>acgwy1</exampleValue>
</param>
</descTemplate>
<manualClearable></manualClearable>
<correctiveAction>None. Acknowledge/Clear alarm and deploy the audiocode server if appropriate.</correctiveAction>
<alarmName>Audiocode Server Updated</alarmName>
<severities>
<severity>MINOR</severity>
</severities>
</alarm>
<alarm>
<eventType>ADMIN</eventType>
<number>2</number>
<probableCause>CONFIG_OR_CUSTOMIZATION_ERROR</probableCause>
<descTemplate>
<msg>Deployment for audiocode server failed: $1. Reason: $2.</msg>
<param>
<num>1</num>
<description>AudioCode Name</description>
<exampleValue>audcod</exampleValue>
</param>
<param>
<num>2</num>
<description>AudioCode Deployment failed reason</description>
<exampleValue>Failed to parse audiocode configuration data</exampleValue>
</param>
</descTemplate>
<manualClearable></manualClearable>
<correctiveAction>Check the configuration of audiocode server. Acknowledge/Clear alarm and deploy the audiocode server if appropriate.</correctiveAction>
<alarmName>Audiocode Server Deploy Failed</alarmName>
<severities>
<severity>MINOR</severity>
</severities>
</alarm>
</alarms>
</family>
</faults>我的代码
from xml.etree import ElementTree
import csv
tree = ElementTree.parse('Fault.xml')
sitescope_data = open('Out.csv', 'w', newline='', encoding='utf-8')
csvwriter = csv.writer(sitescope_data)
#Create all needed columns here in order and writes them to excel file
col_names = ['eventType', 'probableCause', 'severity', 'alarmName', 'shortName', 'longName']
csvwriter.writerow(col_names)
def recurse(root):
for child in root:
recurse(child)
print(child.tag)
for event in root.findall('{urn:nortel:namespaces:mcp:faults}alarm'):
event_data = []
event_id = event.find('{urn:nortel:namespaces:mcp:faults}eventType')
if event_id != None:
event_id = event_id.text
event_data.append(event_id)
probableCause = event.find('{urn:nortel:namespaces:mcp:faults}probableCause')
if probableCause != None:
probableCause = probableCause.text
event_data.append(probableCause)
severities = event.find('{urn:nortel:namespaces:mcp:faults}severities')
if severities:
severity_data = ','.join(
[sv.text for sv in severities.findall('{urn:nortel:namespaces:mcp:faults}severity')])
event_data.append(severity_data)
else:
event_data.append("")
alarmName = event.find('{urn:nortel:namespaces:mcp:faults}alarmName')
if alarmName != None:
alarmName = alarmName.text
event_data.append(alarmName)
csvwriter.writerow(event_data)
root = tree.getroot()
recurse(root)
sitescope_data.close()更新
我很难用这种方式为另一个XML文件解析数据:

对于第一列,我希望获得通用名称标记(recordingSystem、端口等),并将其与行标记(closedFileCount、processedFileCount等)中的subNames连接起来。
我注意到的问题是,subName所在的标签不断变化,可能是“使用”、"lwGuage“、"hwGauge”等等。我也需要收集这些,并把它放在它旁边的专栏。
请参阅下面的示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<omGroups xmlns="urn:nortel:namespaces:mcp:oms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:nortel:namespaces:mcp:oms OMSchema.xsd" >
<group>
<name>RecordingSystem</name>
<row>
<package>com.nortelnetworks.mcp.ne.base.recsystem.fw.system</package>
<class>RecSysFileOMRow</class>
<usage name="closedFileCount" hasThresholds="true">
<measures>
closed file count
</measures>
<description>
This register counts the number
of closed files in the spool directory of a
particular stream and a particular system.
Files in the spool directory store the raw
OAM records where they are sent to the
Element Manager for formatting.
</description>
<notes>
Minor and major alarms
when the value of closedFileCount
exceeds certain thresholds. Configure
the threshold values for minor and major
alarms for this OM through engineering
parameters for minorBackLogCount and
majorBackLogCount, respectively. These
engineering parameters are grouped under
the parameter group of Log, OM, and
Accounting for the logs’ corresponding
system.
</notes>
</usage>
<usage name="processedFileCount" hasThresholds="true">
<measures>
Processed file count
</measures>
<description>
The register counts the number
of processed files in the spool directory of
a particular stream and a particular system.
Files in the spool directory store the raw
OAM records and then send the records to
the Element Manager for formatting.
</description>
</usage>
</row>
<documentation>
<description>
Rows of this OM group provide a count of the number of files contained
within the directory (which is the OM row key value).
</description>
<rowKey>
The full name of the directory containing the files counted by this row.
</rowKey>
</documentation>
<generatedOn>
<all/>
</generatedOn>
</group>
<group traffic="true">
<name>Ports</name>
<row>
<package>com.nortelnetworks.ims.cap.mediaportal.host</package>
<class>PortsOMRow</class>
<usage name="rtpMpPortUsage">
<measures>
BCP port usage
</measures>
<description>
Meter showing number of ports in use.
</description>
</usage>
<lwGauge name="connMapEntriesLWM">
<measures>
Lowest simultaneous port usage
</measures>
<description>
Lowest number of
simultaneous ports detected to be in
use during the collection interval
</description>
</lwGauge>
<hwGauge name="connMapEntriesHWM">
<measures>
Highest simultaneous port usage
</measures>
<description>
Highest number of
simultaneous ports detected to be in
use during the collection interval.
</description>
</hwGauge>
<waterMark name="connMapEntries">
<measures>
Connections map entries
</measures>
<description>
Meter showing the number of connections in the host
CPU connection map.
</description>
<bwg lwref="connMapEntriesLWM" hwref="connMapEntriesHWM"/>
</waterMark>
<counter name="portUsageSampleCnt">
<measures>
Usage sample count
</measures>
<description>
The number of 100-second samples taken during the
collection interval contributing to the average report.
</description>
</counter>
<counter name="sampledRtpMpPortUsage">
<measures>
In-use ports usage
</measures>
<description>
Provides the sum of the in-use ports every 100 seconds.
</description>
</counter>
<precollector>
<package>com.nortelnetworks.ims.cap.mediaportal.host</package>
<class>PortsOMCenturyPrecollector</class>
<collector>centurySecond</collector>
</precollector>
</row>
<documentation>
<description>
</description>
<rowKey>
</rowKey>
</documentation>
<generatedOn>
<list>
<ne>sessmgr</ne>
<ne>rtpportal</ne>
</list>
</generatedOn>
</group>
</omGroups>发布于 2020-09-23 18:25:45
诀窍是在你回溯的时候把家庭信息传递给孩子们。
def recurse(root, family):
for child in root:
if child.tag == '{urn:nortel:namespaces:mcp:faults}family':
family = child
recurse(child, family)
for event in root.findall('{urn:nortel:namespaces:mcp:faults}alarm'):
if family:
event_data = [family.attrib.get('longName',''), family.attrib.get('shortName', '')]
else:
event_data ['','']
recurse(root, None)一种更通用的方法是向下传递一个字典,但是要小心,对字典的更改会冒泡起来,所以最好在修改字典之前复制它:
from copy import copy
def recurse(root, props):
for child in root:
if child.tag == '{urn:nortel:namespaces:mcp:faults}family':
p2 = copy(props)
p2['shortName'] = child.attrib.get('shortName','')
p2['longName'] = child.attrib.get('longName', '')
recurse(child, p2)
else:
recurse(child, props)
for event in root.findall('{urn:nortel:namespaces:mcp:faults}alarm'):
event_data = [props.get('longName',''), props.get('shortName', '')]
recurse(root,{})https://stackoverflow.com/questions/64031471
复制相似问题