加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在Ruby中使用Nokogiri迭代XML嵌套元素

发布时间:2020-12-17 03:48:48 所属栏目:百科 来源:网络整理
导读:我正试图用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"/f
我正试图用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>

因此,我想迭代这个以便能够创建文件夹和文件树(文件夹A1和A2在文件夹A内,文件夹B1和B2在文件夹B内,文件夹B21在文件夹B2内).

所以我这样做:

nodes = allnodes.xpath('//folder')
nodes.each do |node|
  puts "name => #{node.attributes['name']}"
end

但这列出了我所有的文件夹(A,A1,A2,B,B1,B2,B21).我怎么能这样做,以便我不检查以前的文件夹中的更多文件夹,然后我将它发送到相同的递归函数?

非常感谢您的帮助 :)

解决方法

当您使用带有// foo的XPath时,您可以在任何级别找到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

这个的关键是(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

结果:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读