Tia*_*ago 4 ruby xml xpath iterator nokogiri
我正试图用Nokogiri迭代XML格式的文件夹结构,但我陷入了困境:
<test>
<folder name="Folder A">
<folder name="Folder A1">
<file name="a.txt">Cool file</file>
</folder>
<folder name="Folder A2"></folder>
</folder>
<folder name="Folder B">
<folder name="Folder B1"></folder>
<folder name="Folder B2">
<folder name="Folder B21">
<file name="b.txt"></file>
</folder>
</folder>
</test>
Run Code Online (Sandbox Code Playgroud)
因此,我想迭代这个以便能够创建文件夹和文件树(文件夹A1和A2在文件夹A内,文件夹B1和B2在文件夹B内,文件夹B21在文件夹B2内).
所以我这样做:
nodes = allnodes.xpath('//folder')
nodes.each do |node|
puts "name => #{node.attributes['name']}"
end
Run Code Online (Sandbox Code Playgroud)
但这列出了我所有的文件夹(A,A1,A2,B,B1,B2,B21).我怎么能这样做,以便我不检查以前的文件夹中的更多文件夹,然后我将它发送到相同的递归函数?
非常感谢您的帮助 :)
当您使用XPath时,//foo
您可以foo
在任何级别找到元素.如果您改为使用./foo
或只是foo
那时您将只找到子元素.从而:
# Given an XML node, yields the node and all <file> children
# Then recursively does the same with every <folder> child
def process_files_and_folders(node,&blk)
yield node, node.xpath('file')
node.xpath('folder').each{ |folder| process_files_and_folders(folder,&blk) }
end
Run Code Online (Sandbox Code Playgroud)
这个的关键是(a)递归(让所有子文件夹调用本身的方法)和(b)用&blk
符号捕获用户传递的块,然后将该块传递给后面的调用.
看到行动:
require 'nokogiri'
doc = Nokogiri.XML(my_xml)
process_files_and_folders( doc.root ) do |folder,files|
depth = folder.ancestors.length-1 # Just for pretty text output indenting
indent = " "*depth # Just for pretty text output indenting
if folder['name']
puts "#{indent}Processing the folder named #{folder['name']}"
else
puts "#{indent}No folder name; probably the root element."
end
unless files.empty?
puts "#{indent}There are #{files.length} files in '#{folder['name']}':"
files.each{ |file| print indent, file['name'], "\n" }
end
end
Run Code Online (Sandbox Code Playgroud)
结果:
No folder name; probably the root element.
Processing the folder named Folder A
Processing the folder named Folder A1
There are 1 files in 'Folder A1':
a.txt
Processing the folder named Folder A2
Processing the folder named Folder B
Processing the folder named Folder B1
Processing the folder named Folder B2
Processing the folder named Folder B21
There are 1 files in 'Folder B21':
b.txt
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5865 次 |
最近记录: |