Python-如何在具有特定值的两行之间逐行读取文件

时间:2017-10-05 09:34:34

标签: python xml file-io

我正在开发一个Python程序,它将获取另一个程序生成的日志文件(XML),并从中读取数据,只提取我想要的信息,然后将其打印到控制台/将其写入另一个程序文件。

我正在读取的日志文件包含以某种格式写入的数据(许多日志),例如:

2017-05-01 00:00:24 [Client/Report Report] INFO     {'message-id': 'ID:ELX-LVL-ETL01-50079-1493596823959-1:1:1:1:1', 'expires': '1493640024119', 'type': 'MID', 'persistent': 'true', 'destination': '/topic/bmrsTopic', 'timestamp': '1493596824119', 'subscription': 'TtJXJBbtEOcpLrjDsbFD', 'priority': '4'}
<?xml version="1.0" encoding="utf-8"?>
<msgGrp>
    <pubTs>2017-05-01 00:00:24:GMT</pubTs>
    <flow>MID</flow>
<msg>
    <subject>BMRA.SYSTEM.MID</subject>
<row>
    <MI>APXMIDP</MI>
    <SD>2017-05-01 00:00:00:GMT</SD>
    <SP>2</SP>
    <M1>30.620</M1>
    <M2>456.3000</M2>
</row>
</msg>
</msgGrp>

2017-05-01 00:00:39 [Client/Report Report] INFO     {'message-id': 'ID:ELX-LVL-ETL01-59269-1493596838709-1:1:1:1:1', 'expires': '1493640039019', 'type': 'NONBM', 'persistent': 'true', 'destination': '/topic/bmrsTopic', 'timestamp': '1493596839019', 'subscription': 'TtJXJBbtEOcpLrjDsbFD', 'priority': '4'}
<?xml version="1.0" encoding="utf-8"?>
<msgGrp>
    <pubTs>2017-05-01 00:00:38:GMT</pubTs>
    <flow>NONBM</flow>
<msg>
    <subject>BMRA.SYSTEM.NONBM</subject>
    <TP>2017-05-01 00:00:00:GMT</TP>
<row>
    <SD>2017-05-01 00:00:00:GMT</SD>
    <SP>2</SP>
    <NB>0</NB>
</row>
</msg>
</msgGrp>

2017-05-01 00:00:41 [Client/Report  Report] INFO     {'message-id': 'ID:ELX-LVL-ETL01-35161-1493596840568-1:1:1:1:1', 'expires': '1493640040868', 'type': 'INDO', 'persistent': 'true', 'destination': '/topic/bmrsTopic', 'timestamp': '1493596840868', 'subscription': 'TtJXJBbtEOcpLrjDsbFD', 'priority': '4'}
<?xml version="1.0" encoding="utf-8"?>
<msgGrp>
    <pubTs>2017-05-01 00:00:40:GMT</pubTs>
    <flow>INDO</flow>
<msg>
    <subject>BMRA.SYSTEM.INDO</subject>
<row>
    <TP>2017-05-01 00:00:00:GMT</TP>
    <SD>2017-05-01 00:00:00:GMT</SD>
    <SP>2</SP>
    <VD>21627.000</VD>
</row>
</msg>
</msgGrp>

我想阅读每个<msgGrp>&amp;之间的所有信息。 </msgGrp>标记(即实际的XML),并将其附加到String,然后将其转换为XML树。

我已经开始编写Python脚本来执行此操作,并确实正确地阅读了一些信息。我现在正想要读取这两个XML标记之间的所有内容,并将它们附加到字符串中,但我无法弄清楚如何执行此操作...我的Python程序目前看起来像这样: / p>

with open("logFile") as file:
    for line in file:
        if(line.startswith('2017')):
            # Do something
            # Display some output in the console
        elif(line.startswith('<?xml')):
            # Do something else
            # Display some output in the console
        elif(line.startswith('<msgGrp>')):
            xmlString = "";
            while(not(line.startswith('</msgGrp>'))):
                xmlString += line;
            # Display some output in the console
        else:
            # Do something else

当我尝试运行此脚本时,控制台输出显示第一个if&amp; elif成功运行(我在控制台中显示他们的调试),但是当它运行到第二个elif(即我正在处理的那个 - 来读取XML标签中的数据) ),控制台似乎“冻结”一段时间,好像它没有做任何事情,最终显示一条消息说:

  

终止

我猜这是因为在读取这些标记之间的行并将它们附加到变量xmlString时,它会耗尽内存或其他内容(即第二个elif中的代码) ...?

有谁可以向我解释我在这里做错了什么?如何让我的程序成功只读取我指定的两个标签之间的信息,并将其全部附加到我创建的xmlString变量中?

1 个答案:

答案 0 :(得分:2)

   while(not(line.startswith('</msgGrp>'))):
        xmlString += line;

这是一个无限循环(line在外循环中被修改,而不是在while循环中),占用了你机器的所有内存。

你的逻辑在这里打破了。你应该在遇到标记开始时设置一个标志,并累积到主循环中标记的结尾,有些逻辑如下:

    elif(line.startswith('<msgGrp>')):
        start = True
        xmlString = ""

    elif(line.startswith('</msgGrp>'))):
        start = False

    if start:
        xmlString += line

请注意:

  • 连接字符串已经很糟糕了,最好使用io.StringIO或list + join)
  • 使用正确的XML / HTML解析器并不困难,建议使用。解析XML / HTML之类的文本可能会在某些时候中断。