Python使用lxml编写带有系统性能数据的xml文件

时间:2016-09-16 19:07:19

标签: python lxml psutil

我正在使用python模块lxmlpsutil来记录一些系统指标,这些指标要放在XML文件中并复制到远程服务器,以便通过php进行解析并显示给用户。

然而,lxml在将一些变量,对象等推送到我的XML的各个部分时给了我一些麻烦。

例如:

import psutil, os, time, sys, platform
from lxml import etree

# This creates <metrics>
root = etree.Element('metrics')

# and <basic>, to display basic information about the server
child1 = etree.SubElement(root, 'basic')

# First system/hostname, so we know what machine this is
etree.SubElement(child1, "name").text = socket.gethostname()

# Then boot time, to get the time the system was booted.
etree.SubElement(child1, "boottime").text = psutil.boot_time()

# and process count, see how many processes are running.
etree.SubElement(child1, "proccount").text = len(psutil.pids()) 

获取系统主机名的行。

然而接下来的两行用于获取启动时间和进程计数错误,用:

>>> etree.SubElement(child1, "boottime").text = psutil.boot_time()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "lxml.etree.pyx", line 921, in lxml.etree._Element.text.__set__ (src/lxml/lxml.etree.c:41344)
 File "apihelpers.pxi", line 660, in lxml.etree._setNodeText (src/lxml/lxml.etree.c:18894)
 File "apihelpers.pxi", line 1333, in lxml.etree._utf8 (src/lxml/lxml.etree.c:24601)
 TypeError: Argument must be bytes or unicode, got 'float'
>>> etree.SubElement(child1, "proccount").text = len(psutil.pids())
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "lxml.etree.pyx", line 921, in lxml.etree._Element.text.__set__ (src/lxml/lxml.etree.c:41344)
 File "apihelpers.pxi", line 660, in lxml.etree._setNodeText (src/lxml/lxml.etree.c:18894)
 File "apihelpers.pxi", line 1333, in lxml.etree._utf8 (src/lxml/lxml.etree.c:24601)
 TypeError: Argument must be bytes or unicode, got 'int'

所以,这就是我的XML在打印时的样子:

>>> print(etree.tostring(root, pretty_print=True))
<metrics>
  <basic>
    <name>mercury</name>
    <boottime/>
    <proccount/>
  </basic>
</metrics>

那么,无论如何将浮动和整数推送到我需要的xml文本中吗?或者我完全错了吗?

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:2)

text字段应为unicode或str,而不是任何其他类型(boot_timefloatlen()为int)。 因此,只需将非字符串兼容元素转换为字符串:

# First system/hostname, so we know what machine this is
etree.SubElement(child1, "name").text = socket.gethostname() # nothing to do

# Then boot time, to get the time the system was booted.
etree.SubElement(child1, "boottime").text = str(psutil.boot_time())

# and process count, see how many processes are running.
etree.SubElement(child1, "proccount").text = str(len(psutil.pids()))

结果:

b'<metrics>\n  <basic>\n    <name>JOTD64</name>\n    <boottime>1473903558.0</boottime>\n    <proccount>121</proccount>\n  </basic>\n</metrics>\n'

我认为库可以进行isinstance(str,x)测试或str转换,但它不是那样设计的(如果你想用前导零,截断的小数显示你的浮点数怎么办...) 。 如果lib假定所有内容都是str,那么它的运行速度会更快。