Печать данных в список стилей (таблицы) из XML в Python - PullRequest
3 голосов
/ 16 декабря 2011

Я хотел бы распечатать свои серверы, как указано в списке. Как это:

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 ]

4 голосов
/ 16 декабря 2011

Прежде всего, вы не можете напечатать строки сразу; лучше хранить данные (в виде кортежей) в списке (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
2 голосов
/ 16 декабря 2011

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