【问题标题】:XML file parsing with Python使用 Python 解析 XML 文件
【发布时间】:2021-01-20 16:46:03
【问题描述】:

我无法以这种方式解析转换为 CSV 的 XML 文件的数据:

对于第一列,我想获取通用名称标签(recordingSystem、Ports 等)并将其与行标签中的子名称(closedFileCount、processedFileCount 等)连接起来

subName 所在的标签不断变化,可能是“usage”、“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>

下面的代码应该获取 GeneralName 并在 csv 文件中显示正确的次数,但我无法让它显示任何内容。

from xml.etree import ElementTree
import csv
from copy import copy

import lxml.etree



tree = ElementTree.parse('OM.xml')

sitescope_data = open('OMFileConverted.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 = ['name', 'OMRegister']
csvwriter.writerow(col_names)

def recurse(root, props):
    for child in root:
        if child.tag == '{urn:nortel:namespaces:mcp:oms}group':
            p2 = copy(props)
            for event in root.findall('{urn:nortel:namespaces:mcp:oms}group'):
                event_id = event.find('{urn:nortel:namespaces:mcp:oms}name')
                if event_id != None:
                    p2['name'] = event_id.text
                    recurse(child, p2)
                else:
                    recurse(child, props)


    for event in root.findall('{urn:nortel:namespaces:mcp:oms}group'):

        event_data = [props.get('name')]



        csvwriter.writerow(event_data)



root = tree.getroot()
recurse(root,{}) #root + empty dictionary
sitescope_data.close()

【问题讨论】:

  • 你能用beautifulsoup吗?
  • 如果beautifulsoup可以像csv截图那样解析xml,那就太好了

标签: python xml csv parsing elementtree


【解决方案1】:

如果xml_string 是问题中的 XML sn-p,那么这个脚本:

import csv
from bs4 import BeautifulSoup

soup = BeautifulSoup(xml_string, 'html.parser')

with open('data.csv', 'w', newline='') as f_out:
    writer = csv.writer(f_out)
    writer.writerow(['General name:SpecificName', 'RegisterType'])
    for item in soup.select('row [name]'):
        writer.writerow([item.find_previous('name').text + ':' + item['name'], item.name])

生成 data.csv(来自 LibreOffice 的屏幕截图):


编辑:要将measures 标签放入一列,您可以:

import csv
from bs4 import BeautifulSoup

soup = BeautifulSoup(xml_string, 'html.parser')

with open('data.csv', 'w', newline='') as f_out:
    writer = csv.writer(f_out)
    writer.writerow(['General name:SpecificName', 'RegisterType', 'Measures'])
    for item in soup.select('row [name]'):
        writer.writerow([item.find_previous('name').text + ':' + item['name'], item.name, item.find('measures').get_text(strip=True)])

生产:

【讨论】:

  • 如果您不介意,我还有一个问题。如果我还想为嵌套的measures 标签创建一个列,我该怎么做?
  • @marcorivera8 可以使用item.find('measures').text,然后写入csv。
  • 我在同一个 for 循环中做了writer.writerow([item.find_previous('name').text + ':' + item['name'], item.name,item.find('measures').text]),但它不起作用
  • 嗨@Andrej Kesely,我更新了这篇文章,提出了另一个问题,如果你有时间可以看一下。谢谢
  • @marcorivera8 你能把更新作为新问题发布在这里吗? (为了不弄乱评论部分和回答的问题)。你可以事后通知我,我看看。
猜你喜欢
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 2015-11-18
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
相关资源
最近更新 更多