Печать данных в список стилей (таблица) из 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-адреса и выглядеть как таблица.

Нужна помощь..

Прежде всего, вы не можете распечатать строки сразу; скорее сохраните данные (в виде кортежей) в списке ( servers ). Чтобы сгруппировать службы по машине / группе / IP, вы можете использовать itertools функций groupby , указав первые три поля в качестве ключевого кортежа. (Перед этим список должен быть отсортирован, поэтому groupby находит все дубликаты.) groupby дает ключ (3-кортеж) и генератор для остальных соответствующих строк; здесь нас интересуют уникальные значения четвертого значения (службы), поэтому мы преобразуем значения в set и соединим их по пробелам.

Проблема с выравниванием таблицы может быть решена с помощью string функции ljust (выравнивание по левому 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 

Я думаю, вам нужно использовать мини-язык спецификации формата, доступный в 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