Форум сайта python.su
Добрый всем день, питон начал изучать совсем недавно, читаю учебник на интуите, дошёл до xml. Поставил себе задачку, сформировать структуру файлов и директорий в xml файл. Вот такое решение у меня получилось с использованием SAX:
#!/usr/bin/python
from xml.sax.saxutils import XMLGenerator
import os,sys,datetime
class dir2xml:
def __init__(self,filename="tree_%s.xml"%datetime.date.today()):
self.filename=filename
try:
self.fh=open(filename,"w")
except IOError,error:
print error.err
return error.err
try:
self.xml=XMLGenerator(self.fh)
except:
print "Error creating XML object"
return -1
def __del__(self):
self.fh.close()
def toxml(self,dir_):
self.xml.startElement("directory",{"dirname":dir_})
items=os.listdir(dir_)
for item in items:
fullname=os.path.join(dir_,item)
if os.path.isdir(fullname):
self.toxml(fullname)
else:
ext=item.split(".")
self.xml.startElement("file",{"size":str(os.path.getsize(fullname)),"type":ext[-1]})
self.xml.characters(item)
self.xml.endElement("file")
self.xml.endElement("directory")
a=dir2xml()
a.toxml(sys.argv[1])
#!/usr/bin/python
from xml.dom import minidom
import os,sys,datetime
class dir2xml:
def __init__(self,filename="tree_%s.xml"%datetime.date.today()):
self.filename=filename
try:
self.fh=open(filename,"w")
except IOError,error:
print error.err
return error.err
try:
self.dom=minidom.Document()
except:
print "Error creating XML object"
return -1
def __del__(self):
self.fh.close()
def toxml(self,dir_):
e1=self.dom.createElement("Directory")
e1.setAttribute("dirname",dir_)
self.dom.appendChild(e1)
items=os.listdir(dir_)
for item in items:
fullname=os.path.join(dir_,item)
if os.path.isdir(fullname):
self.toxml(fullname)
else:
ext=item.split(".")
e2=self.dom.createElement("file")
e2.setAttribute("size",str(os.path.getsize(fullname)))
e2.setAttribute("type",ext[-1])
e2.appendChild(self.dom.createTextNode(item))
e1.appendChild(e2)
return self.dom
a=dir2xml()
xml=a.toxml(sys.argv[1])
print xml.toprettyxml()
Отредактировано (Сен. 1, 2009 11:31:51)
Офлайн
Если тебе это нужно практически то не имеет смысла использовать для этого xml.
Офлайн
baluну на самом деле, тут основная цель - решить задачу и получить какой никакой навык ) ну а ко всему прочему, надо есть желание написать скрипт для подбивания изменений в дереве, с учётом размера и сохранением статистики.
Если тебе это нужно практически то не имеет смысла использовать для этого xml.
Офлайн
У вас при рекурсивном вызове toxml в него должна передаваться нода в которую будут вставляться данные подкаталога, а сейчас вы пытаетесь вставить несколько элементов в корень XML, а по стандарту он должен быть один, о чем вам питон и ругается.
Ну и вообще, зачем организовывать класс там где достаточно функции? открытие файла в __init__ и закрытие в __del__ - не делайте так. параметр filename в __init__ по умолчанию - потенциально опасно лучше поставить filename=None, а в методе уже проверить и вычислить. Ошибки съедаете в try/except - мне как пользователю лучше видеть трайсбэк, а не ваше невнятное “ну не шмогла я, не шмогла”. Да и вообще я бы формировал XML не через minidom, а простым текстовым выводом.
Ну как то вот так :rolleyes:
Офлайн
xostУ меня этот пример работает вполне себе нормально и формирует вложенную структуру каталогов и файлы в них.
Что забавно, нарыл вот эту ссылку: http://code.activestate.com/recipes/305313/ уже после того как сначала сюда вопрос запостил, но тоже выдаёт только список файлов в директории первого уровня.
Офлайн
xostЕсли цель получить навык работы xml или передать куда-то данные, то это одно дело.
ну на самом деле, тут основная цель - решить задачу и получить какой никакой навык
Офлайн
PooHСпасибо за подсказку про ноду, всё получилось :) ну а что касается того что зря я всё это классом и try/except так это обусловлено исключительно что я учусь и стараюсь пробовать как можно больше возможностей, ньюансов использовать, пусть даже и неоправданно, чтоб так сказать на корочку записалось. Простым SAX у меня достаточно быстро получилось всё реализовать, но для дальнейшей задумки скрипта мне кажется не плохо было бы работать с DOM объектом, вот и заморочился.
У вас при рекурсивном вызове toxml в него должна передаваться нода в которую будут вставляться данные подкаталога, а сейчас вы пытаетесь вставить несколько элементов в корень XML, а по стандарту он должен быть один, о чем вам питон и ругается.
Ну и вообще, зачем организовывать класс там где достаточно функции? открытие файла в __init__ и закрытие в __del__ - не делайте так. параметр filename в __init__ по умолчанию - потенциально опасно лучше поставить filename=None, а в методе уже проверить и вычислить. Ошибки съедаете в try/except - мне как пользователю лучше видеть трайсбэк, а не ваше невнятное “ну не шмогла я, не шмогла”. Да и вообще я бы формировал XML не через minidom, а простым текстовым выводом.
Ну как то вот так :rolleyes:
Отредактировано (Сен. 1, 2009 15:11:13)
Офлайн
baluДа, я ж написал, первоочередная цель - получить навык :) Но за ваше мнение спасибо :)xostЕсли цель получить навык работы xml или передать куда-то данные, то это одно дело.
ну на самом деле, тут основная цель - решить задачу и получить какой никакой навык
Если цель задачи - создать дерево, то это из пушки по воробьям http://alexott-ru.blogspot.com/2009/01/xml.html.
Офлайн
xostЗначения параметров по умолчанию вычисляются в момент когда метод определяется. Если ваш класс будет использован в постоянно работающей программе, то файл будет создаваться с одним и тем же именем - с датой запуска программы
PS: объясните, пожалуйста, почему filename по умолчанию опасно в __init__ ?
xostПо той же причине, что и в Java: момент вызова __del__ точно не определен, это не C++. Да и вообще, чем меньшее время открыт ресурс (в данном случае файл) тем лучше.
и почему открытие и закрытие файла в __init__ , __del__ не делать ?
Офлайн
PooHОк, спасибо за разъяснения.xostЗначения параметров по умолчанию вычисляются в момент когда метод определяется. Если ваш класс будет использован в постоянно работающей программе, то файл будет создаваться с одним и тем же именем - с датой запуска программы
PS: объясните, пожалуйста, почему filename по умолчанию опасно в __init__ ?xostПо той же причине, что и в Java: момент вызова __del__ точно не определен, это не C++. Да и вообще, чем меньшее время открыт ресурс (в данном случае файл) тем лучше.
и почему открытие и закрытие файла в __init__ , __del__ не делать ?
Офлайн