我必須監視一整天運行的工具所寫的XML文件。但是XML文件只能在一天結束時正確完成並關閉。在編寫XML文件時(使用Python)
相同的約束作爲XML流處理:
- 解析上即時不完整的XML文件,並觸發動作
- 從一開始就再次保留在文件中軌道的最後一個位置,以避免處理它
論Need to read XML files as a stream using BeautifulSoup in Python答案,slezica建議xml.sax
,xml.etree.ElementTree
和cElementTree
。但是,我嘗試使用xml.etree.ElementTree
和cElementTree
沒有成功。也有xml.dom
,xml.parsers.expat
和lxml
但我沒有看到支持「即時解析」。
我需要更明顯的例子...
我目前正在使用Python 2.7在Linux上,但我會遷移到Python 3.x都有=>也請提供新的Python 3.x的功能提示。我還使用watchdog
來檢測XML文件修改=>可以重複使用watchdog
機制。也可以選擇支持Windows。
請提供易於理解/維護解決方案。如果它太複雜,我可能只使用tell()
/seek()
在文件中移動,在原始XML中使用愚蠢的文本搜索,最後使用基本正則表達式提取值。
XML示例:
<dfxml xmloutputversion='1.0'>
<creator version='1.0'>
<program>TCPFLOW</program>
<version>1.4.6</version>
</creator>
<configuration>
<fileobject>
<filename>file1</filename>
<filesize>288</filesize>
<tcpflow packets='12' srcport='1111' dstport='2222' family='2' />
</fileobject>
<fileobject>
<filename>file2</filename>
<filesize>352</filesize>
<tcpflow packets='12' srcport='3333' dstport='4444' family='2' />
</fileobject>
<fileobject>
<filename>file3</filename>
<filesize>456</filesize>
...
...
首先測試使用SAX失敗:
import xml.sax
class StreamHandler(xml.sax.handler.ContentHandler):
def startElement(self, name, attrs):
print 'start: name=', name
def endElement(self, name):
print 'end: name=', name
if name == 'root':
raise StopIteration
if __name__ == '__main__':
parser = xml.sax.make_parser()
parser.setContentHandler(StreamHandler())
with open('f.xml') as f:
parser.parse(f)
外殼:
$ while read line; do echo $line; sleep 1; done <i.xml >f.xml &
...
$ ./test-using-sax.py
start: name= dfxml
start: name= creator
start: name= program
end: name= program
start: name= version
end: name= version
Traceback (most recent call last):
File "./test-using-sax.py", line 17, in <module>
parser.parse(f)
File "/usr/lib64/python2.7/xml/sax/expatreader.py", line 107, in parse
xmlreader.IncrementalParser.parse(self, source)
File "/usr/lib64/python2.7/xml/sax/xmlreader.py", line 125, in parse
self.close()
File "/usr/lib64/python2.7/xml/sax/expatreader.py", line 220, in close
self.feed("", isFinal = 1)
File "/usr/lib64/python2.7/xml/sax/expatreader.py", line 214, in feed
self._err_handler.fatalError(exc)
File "/usr/lib64/python2.7/xml/sax/handler.py", line 38, in fatalError
raise exception
xml.sax._exceptions.SAXParseException: report.xml:15:0: no element found