从XML在Python中以列表样式(表格)打印数据
我想把我的服务器按照列表的方式打印出来。像这样:
Machine | Group | IP | Services
- Alpha | Public Server Group | 192.168.1.251 | JBoss, Tomcat
- Public | Public Server Group | 192.168.1.253 | JBoss, Tomcat
我的XML内容是:
<?xml version="1.0" ?>
<AllConfigurations>
<DeployConfigurations>
<Servers>
<Group id="1" name="Public Server Group" username="root" password="mypasswd123" state="">
<GApp id="1" name="JBoss Servers" type="JBoss" path="/root/Desktop/jboss-as-7.0.2.Final/" state="">
<Server id="1" name="Alpha" ip="192.168.1.251" path="/root/Desktop/jboss-as-7.0.2.Final/" username="" password="" state="" />
<Server id="2" name="Public" ip="192.168.1.253" path="/root/Desktop/jboss-as-7.0.2.Final/" username="" password="" state="" />
</GApp>
<GApp id="2" name="Tomcat Servers" type="Tomcat" path="/root/Desktop/apache-tomcat-7.0.22/" state="">
<Server id="1" name="Alpha" ip="192.168.1.251" path="/root/Desktop/apache-tomcat-7.0.22/" username="" password="" state="" />
<Server id="2" name="Public" ip="192.168.1.253" path="/root/Desktop/apache-tomcat-7.0.22/" username="" password="" state="" />
</GApp>
</Group>
</Servers>
</DeployConfigurations>
</AllConfigurations>
我正在尝试这样做:
from xml.dom.minidom import parse
yXML = parse('/root/Desktop/gb/data/yConfig.xml')
print (' ')
print ('Machine | Group | IP | Services')
for AllConfigurations in yXML.getElementsByTagName('AllConfigurations'):
for DeployConfigurations in AllConfigurations.getElementsByTagName('DeployConfigurations'):
for Servers in DeployConfigurations.getElementsByTagName('Servers'):
for Group in Servers.getElementsByTagName('Group'):
for GApp in Group.getElementsByTagName('GApp'):
for Server in Group.getElementsByTagName('Server'):
print Server.getAttribute('name') + ' | ' + Group.getAttribute('name') + ' | ' + Server.getAttribute('ip') + ' | ' + GApp.getAttribute('type')
我的结果是:
Machine | Group | IP | Services
Alpha | Public Server Group | 192.168.1.251 | JBoss
Public | Public Server Group | 192.168.1.253 | JBoss
Alpha | Public Server Group | 192.168.1.251 | JBoss
Public | Public Server Group | 192.168.1.253 | JBoss
Alpha | Public Server Group | 192.168.1.251 | Tomcat
Public | Public Server Group | 192.168.1.253 | Tomcat
Alpha | Public Server Group | 192.168.1.251 | Tomcat
Public | Public Server Group | 192.168.1.253 | Tomcat
我该怎么做呢?
它会为每一种可能性都打印出来。我无法把服务并排对齐,只能为一个IP打印,看起来像个表格。
需要帮助..
2 个回答
2
我觉得你需要利用Python中的一种叫做格式规范小语言的东西:
data = ('Machine', 'Group', 'IP', 'Services')
# left aligned (default)
print '{0:20} | {1:20} | {2:20} | {3:20}'.format(*data)
# rigth aligned (default)
print '{0:>20} | {1:>20} | {2:>20} | {3:>20}'.format(*data)
# centered
print '{0:^20} | {1:^20} | {2:^20} | {3:^20}'.format(*data)
上面脚本的输出结果是:
Machine | Group | IP | Services
Machine | Group | IP | Services
Machine | Group | IP | Services
4
首先,你不能直接打印出这些行,而是要把数据存储在一个列表里(叫做 servers
),每条数据用元组的形式保存。为了按机器、组或IP来分组服务,你可以使用 itertools
里的 groupby
函数,并把前三个字段作为关键元组来指定。(在这之前,列表需要先排序,这样 groupby
才能找到所有重复的项。)groupby
会返回一个关键元组(3个元素的元组)和一个生成器,用来获取对应的其他行;在这里,我们关注的是第四个值(服务)的唯一值,所以我们把这些值转换成一个 set
(集合),并用空格把它们连接起来。
关于对齐表格的问题,可以通过使用 string
里的 ljust
函数(左对齐)来解决。我还写了一个单独的函数,用来通用化表头和数据行的渲染。
下面是代码:
from itertools import groupby
servers = []
for AllConfigurations in yXML.getElementsByTagName('AllConfigurations'):
for DeployConfigurations in AllConfigurations.getElementsByTagName('DeployConfigurations'):
for Servers in DeployConfigurations.getElementsByTagName('Servers'):
for Group in Servers.getElementsByTagName('Group'):
for GApp in Group.getElementsByTagName('GApp'):
for Server in Group.getElementsByTagName('Server'):
servers.append((Server.getAttribute('name'),
Group.getAttribute('name'),
Server.getAttribute('ip'),
GApp.getAttribute('type')))
def line(machine, group, ip, services):
return " | ".join([machine.ljust(8), group.ljust(20), ip.ljust(15), services])
print line("Machine", "Group", "IP", "Services")
for server, services in groupby(sorted(servers), lambda server: server[0:3]):
print line("- " + server[0], server[1], server[2],
", ".join(service[3] for service in set(services)))
这段代码会打印出:
Machine | Group | IP | Services
- Alpha | Public Server Group | 192.168.1.251 | JBoss, Tomcat
- Public | Public Server Group | 192.168.1.253 | Tomcat, JBoss