Разбор вложенного XML с использованием Python - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь проанализировать вложенный XML с помощью python. Пример файла формата выглядит следующим образом

<repositoryFileTreeDto>
    <children>
        <children>
            <file>
                <name> File1 </name>
                <path> home/user1/File1.txt </path>
            </file>
        </children>
        <children>
            <file>
                <name> File2 </name>
                <path> home/user1/File2.txt </path>
            </file>
        </children>
        <file>
            <name> User1 </name>
            <path> home/user1 </path>
        </file>
    </children>
    <children>
        <file>
            <name> User2 </name>
            <path> home/user2 </path>
        </file>
    </children>
    <children>
        <file>
            <name> User3 </name>
            <path> home/user3 </path>
        </file>
    </children>
    <children>
        <children>
            <file>
                <name> File4 </name>
                <path> home/user4/File4.txt </path>
            </file>
        </children>
        <file>
            <name> User4 </name>
            <path> home/user4 </path>
        </file>
    </children>
    <file>
        <name> Home </name>
        <path> /home </path>
    </file>
</repositoryFileTreeDto>

Я хочу напечатать пустые папки использования и непустые папки пользователей (то есть пользователей с 1 или более файлами).

Здесь, во фрагменте XML.

Пользователь 2 и Пользователь 3 являются пустыми папками, а пользователь 1 является непустым пользователем.

Условие для идентификации пустых и непустых пользователей:

Если у пользователя есть какой-либо тег на том же уровне, то не пустой пользователь Если у пользователя нет тега, то это пустой пользователь.

Пример кода 1:

import xml.etree.ElementTree as ET
import time
import requests
import csv
tree = ET.parse('tree.xml')
root = tree.getroot()
for child in root.findall('children'):
    for subchlid in child.findall('file'):
        title = subchlid.find('title').text
        print(title)
    for subchlid1 in child.findall('children'):
        if subchlid1.tag == 'children':
            print(subchlid1.tag)

Кодовый вывод 1:

User1
File1
File2
User2
User3
User4
File4

Пример кода 2:

import xml.etree.ElementTree as ET
import time
import requests
import csv
tree = ET.parse('tree.xml')
root = tree.getroot()
list_values = []
dicts = {}
for child in root.findall('children'):
    for sub_child in child.findall('file'):
        username = sub_child.find('title').text

    for sub_child1 in child.findall('children'):
        for sub_child2 in sub_child1.findall('file'):
            file_path = sub_child2.find('path').text
            file_title = sub_child2.find('title').text
        #print(username)
        #print(file_title)
        list_values.append(file_title)
        for user in username:
            dicts[username] = list_values
print(dicts)

Кодовый вывод 2:

{'User1': ['File1', 'File2'],'User4': ['File1', 'File2', 'File4']}

Здесь в этом выводе User2 и User3 не являются частью Dict, потому что это пустая папка, а User4 делится файлами User1.

Ожидаемый результат:

The number of Empty Users: 2
The number of Non-Empty Users: 2
User1 Files are: File1, File2
User4 files are: File4

Спасибо всем, ребята.

1 Ответ

0 голосов
/ 28 июня 2018

Если вы открыты для использования пакета lxml, вы можете использовать xpath для получения результата.

from lxml import etree
from operator import itemgetter
from collections import defaultdict

first = itemgetter(0)
with open('tree.xml') as fp:
    xml = etree.fromstring(fp.read())

# create a user dictionary and a file dictionary
udict = {first(e.xpath('path/text()')).strip(): first(e.xpath('name/text()')).strip()
         for e in xml.xpath('children/file')}

fdict = {first(e.xpath('path/text()')).strip(): first(e.xpath('name/text()')).strip()
         for e in xml.xpath('children/children/file')}

ufdict = defaultdict(list)

for k,v in fdict.items():
    ufdict[first(k.rsplit('/',1))].append(v)

out = {v: ufdict.get(k, []) for k, v in udict.items()}

print('The number of Empty Users: {}'.format(len([v for v in out.values() if not v]))
print('The number of Non-Empty Users: {}'.format(len([v for v in out.values() if not v]))
for k, v in out.items():
    if v:
        print(f'{k} files are {", ".join(v)}')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...