Уведомления

Группа в Telegram: @pythonsu

#1 Июль 19, 2017 21:52:03

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

в 2.7 - pip install lxml, в принципе и 3.5 достаточно
ну вы таки распарсили xml,  получили список таблиц в формате тэг/аттрибуты/текст, идите дальше
например список файлов

 from lxml import etree
    
def get_node(node,lst):
    lst.append([node.tag,node.attrib,node.text])
    for n in node:
        get_node(n,lst)
    
tree = etree.parse('DBSchema.xml')
out = []
for t in tree.getroot():
    get_node(t,out)
    
names = []
for i in out:
    if i[0] == 'table':
        names.append(i[1]['name'])
    
for name in names:
    print(name +'.xml') #for example


Офлайн

#2 Июль 19, 2017 23:40:41

evp24
Зарегистрирован: 2017-05-03
Сообщения: 96
Репутация: +  3  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

С помощью текстового редактора, удалось привести xml файл в более менее божеский вид (распарсить)
за основу пока, взял файл отсюда

там категории, подкатегории и товары
интересно получилось, привести его к формату csv руками, с помощью excel (calc)

"a78bd1c1-9c01-11e1-a650-0800272c283f"	"3bbb0ba3-a0b3-11e1-b16e-0800272c283f"	"false"	"0000000011"	"Посуда"	

1. ряд - родитель
2. ряд - не разобрался еще, но видимо определяет родителя
3. ряд - если false - то это категория (родительская или дочерняя), если true то - товар с родительской категорией указанной во 2 столбце
4. ряд - не знаю, может код товара
5. ряд - “наименование”


========================
как можно это привести в приличный вид:

- родитель (папка)
– подпапка
— подпапка подпапки если есть…
— товар

все только 5 рядом или в таблице, чтоб можно было отсортировать.

Или вообще, делается?


Или сначала - берем 1 колонку первой строки где есть false
ищем ее во второй колонке 1 строки, 2 строки …. всех строк
если находим совпадение - то переименовываем Значение в первой строке первой колонке в “1” вместо этого длинного!
берем вторую строку первую колонку
ищем совпадение во всех строках во второй колонке
если находим совпадение - изменяем первую колонку второй строки на предыдущее значение (строки выше +1)

понятно, что это можно сделать и руками… в ехсele )

Прикреплённый файлы:
attachment tovari.csv (440,7 KБ)

Офлайн

#3 Июль 20, 2017 01:19:54

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

 да все делается, но у вас алгоритм путаный какой-то(неформализованный)
ЕЯПП метод такой

 f= open('tovari.csv')
lines  = f.readlines()
f.close()
data = []
for i in lines:
    data.append(i.split('\t'))
lst = []
for i in data:
    if i[2] == '"false"':
        lst.append(i)
for i in lst:
    for j in data:
        if i[0] == j[1]:
            j[0] = '1'
f = open('result.txt','w')
for i in data:
    f.write('\t'.join(i) + '\n')
f.close()

Отредактировано vic57 (Июль 20, 2017 01:41:24)

Офлайн

#4 Июль 20, 2017 07:48:15

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

vic57
у вас алгоритм путаный какой-то
Извините да просто каша в голове. Ну нельзя разбить на папки и товары. если в таблице категории и наименования. Хотябы тут надо четко везде одинаковую терминологию использовать.
Построить дерево названий товаров задача элементарная.
 from collections import defaultdict
class Folder:
    def __init__(self):
        folders=[]
        products=[]
folders=defaultdict(Folder)
for i in f.lines():
   self_id, parent_folder_id, g1, is_product,g2,name =i.split("\t")
   if is_product:
      folders[parent_folder_id].products.append(name)
   else:
      folders[parent_folder_id].folders.append(folders[self_id])

Только вы со своим екселем выкинули self_id без которого нельзя построить дерево



Офлайн

#5 Июль 24, 2017 09:59:49

evp24
Зарегистрирован: 2017-05-03
Сообщения: 96
Репутация: +  3  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

vic57
например список файлов

А можно в такой формат вывести?

table1,field1, int, true
table1,field2, string, false
table2,field1, int, true
table2,field2, string, false


<tables>
<table name="SystemSettings" prop1="78" prop2="1" prop3="83">
<fields>
<field name="UserId" td="string(0::2147483712:0:0)"/>
<field name="ObjectKey" td="string(0::2147483904:0:0)"/>
<field name="SettingsKey" td="string(0::2147483904:0:0)"/>
<field name="Version" td="binary(0::16:0:0)"/>
<field name="SettingsPresentation" null="true" td="string(0::2147483904:0:0)"/>
<field name="SettingsData" null="true" td="binary(0::2147483648:0:0)"/>
</fields>
<indexes>
<index name="ByKey" fields="UserId|ObjectKey|SettingsKey" prop2="1"/>
</indexes>
</table>
<table name="CommonSettings" prop1="78" prop2="2" prop3="83">
<fields>
<field name="UserId" td="string(0::2147483712:0:0)"/>
<field name="ObjectKey" td="string(0::2147483904:0:0)"/>
<field name="SettingsKey" td="string(0::2147483904:0:0)"/>
<field name="Version" td="binary(0::16:0:0)"/>
<field name="SettingsPresentation" null="true" td="string(0::2147483904:0:0)"/>
<field name="SettingsData" null="true" td="binary(0::2147483648:0:0)"/>
</fields>
<indexes>
<index name="ByKey" fields="UserId|ObjectKey|SettingsKey" prop2="1"/>
</indexes>
</table>

а уже потом, создав таблицы из списка, можно в них все загнав, работать с запросами

Офлайн

#6 Июль 24, 2017 12:56:26

evp24
Зарегистрирован: 2017-05-03
Сообщения: 96
Репутация: +  3  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

vic57
f= open('tovari.csv')
lines = f.readlines()
f.close()
data = []
for i in lines:
data.append(i.split('\t'))
lst = []
for i in data:
if i[2] == '"false"':
lst.append(i)
for i in lst:
for j in data:
if i[0] == j[1]:
j[0] = '1'
f = open('result.txt','w')
for i in data:
f.write('\t'.join(i) + '\n')
f.close()

Меняю if i[2] == '"false"': на if i[4] == '"false"':
в новом файле (с сохранением всех опций

выдает ошибку:

Traceback (most recent call last):
File "/home/irip/netbeabs-py/xml/xml-test/src/index.py", line 9, in <module>
if i[4] == '"false"':
IndexError: list index out of range

Отредактировано evp24 (Июль 24, 2017 12:58:03)

Прикреплённый файлы:
attachment tovari2.csv (489,3 KБ)

Офлайн

#7 Июль 24, 2017 13:07:07

evp24
Зарегистрирован: 2017-05-03
Сообщения: 96
Репутация: +  3  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

Горизонтальная табуляция
стоит, как разделитель между кавычками

Офлайн

#8 Июль 24, 2017 13:34:42

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

evp24
выдает ошибку:

Traceback (most recent call last):
File “/home/irip/netbeabs-py/xml/xml-test/src/index.py”, line 9, in <module>
if i == ‘“false”’:
IndexError: list index out of range
вы формат файла поменяли, в нем нет ‘\t’

Офлайн

#9 Июль 24, 2017 13:46:03

evp24
Зарегистрирован: 2017-05-03
Сообщения: 96
Репутация: +  3  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

vic57
в нем нет ‘\t’

А если там “id_”,“название”

Офлайн

#10 Июль 24, 2017 13:49:28

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

xml множество файлов в разных папках собрать воедино

 from lxml import etree
xml='''<table name="SystemSettings" prop1="78" prop2="1" prop3="83">
      <fields>
        <field name="UserId" td="string(0::2147483712:0:0)"/>
        <field name="ObjectKey" td="string(0::2147483904:0:0)"/>
        <field name="SettingsKey" td="string(0::2147483904:0:0)"/>
        <field name="Version" td="binary(0::16:0:0)"/>
        <field name="SettingsPresentation" null="true" td="string(0::2147483904:0:0)"/>
        <field name="SettingsData" null="true" td="binary(0::2147483648:0:0)"/>
      </fields>
      <indexes>
        <index name="ByKey" fields="UserId|ObjectKey|SettingsKey" prop2="1"/>
      </indexes>
    </table>
'''
def get_node(node,lst):
    attr = node.attrib
    if attr: lst.append([node.tag,attr])
    for n in node:
        get_node(n,lst)
    
tree = etree.fromstring(xml)
out = []
get_node(tree,out)
for i in out:
    print i
получите список типа
['table', {'prop3': '83', 'name': 'SystemSettings', 'prop2': '1', 'prop1': '78'}]
['field', {'td': 'string(0::2147483712:0:0)', 'name': 'UserId'}]
['field', {'td': 'string(0::2147483904:0:0)', 'name': 'ObjectKey'}]
['field', {'td': 'string(0::2147483904:0:0)', 'name': 'SettingsKey'}]
['field', {'td': 'binary(0::16:0:0)', 'name': 'Version'}]
['field', {'td': 'string(0::2147483904:0:0)', 'null': 'true', 'name': 'SettingsPresentation'}]
['field', {'td': 'binary(0::2147483648:0:0)', 'null': 'true', 'name': 'SettingsData'}]
['index', {'fields': 'UserId|ObjectKey|SettingsKey', 'name': 'ByKey', 'prop2': '1'}]
что хотите из него загонять в таблицу?
RTFM, имхо вы не понимаете что делаете

Отредактировано vic57 (Июль 24, 2017 14:24:44)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version