データから XML を作成する場合は、実際にはツリー状の構造を作成する必要があります。ElementTree
これは、構築して注釈を付け、場合によっては反復またはトラバースしてから、 XML を作成するために に変換する中間ツリーにすることができます。または、 lxmlの ElementTree APIElementTree
を使用して直接構築することもできます。
いずれにせよ、使用os.walk()
する方法はありません。これは直感に反するように聞こえるかもしれませんが、要点は次のとおりos.walk()
です。ファイル システム ツリーをシリアル化 (フラット化) するので、簡単に反復処理を行うことができ、それを行う再帰関数を記述する必要はありません。ただし、あなたの場合、ツリー構造を保持したいので、その再帰関数を自分で記述した方がはるかに簡単です。
ElementTree
これは、を使用してを構築する方法の例ですlxml
。
(このコードは、同様の質問に対する @MikeDeSimone の回答に大まかに基づいています)
import os
from lxml import etree
def dir_as_tree(path):
"""Recursive function that walks a directory and returns a tree
of nested etree nodes.
"""
basename = os.path.basename(path)
node = etree.Element("node")
node.attrib['name'] = basename
# Gather some more information on this path here
# and write it to attributes
# ...
if os.path.isdir(path):
# Recurse
node.tag = 'dir'
for item in sorted(os.listdir(path)):
item_path = os.path.join(path, item)
child_node = dir_as_tree(item_path)
node.append(child_node)
return node
else:
node.tag = 'file'
return node
# Create a tree of the current working directory
cwd = os.getcwd()
root = dir_as_tree(cwd)
# Create an element tree from the root node
# (in order to serialize it to a complete XML document)
tree = etree.ElementTree(root)
xml_document = etree.tostring(tree,
pretty_print=True,
xml_declaration=True,
encoding='utf-8')
print xml_document
出力例:
<?xml version='1.0' encoding='utf-8'?>
<dir name="dirwalker">
<dir name="top1">
<file name="foobar.txt"/>
<dir name="sub1"/>
</dir>
<dir name="top2">
<dir name="sub2"/>
</dir>
<dir name="top3">
<dir name="sub3">
<dir name="sub_a"/>
<dir name="sub_b"/>
</dir>
</dir>
<file name="topfile1.txt"/>
<file name="walker.py"/>
</dir>