解析递归收集具有父级ID的深层嵌套类别XML子级

时间:2019-05-02 21:10:53

标签: ruby xml xml-parsing nokogiri

我有一个带有id和name属性的XML文件。

    <?xml version="1.0" encoding="UTF-8"?>
     <product_categories>
       <product_category id="409" name="Computer">
          <product_category id="414" name="Server">
             <product_category id="511" name="Multimedia Server"/>
          </product_category>
          <product_category id="1645" name="Server Equips"/>
       </product_category>
       <product_category id="97" name="Computer Equips">
          <product_category id="127" name="Adaptor">
             <product_category id="133" name="Audior"/>
             <product_category id="128" name="DVI"/>
             <product_category id="134" name="Firewire"/>
             <product_category id="135" name="Gender Changer"/>
             <product_category id="129" name="HDMI - DVI / DVI-I"/>
             <product_category id="137" name="HDMI"/>
             <product_category id="139" name="Keyboard"/>
             <product_category id="141" name="Mouse"/>
             <product_category id="144" name="Scart"/>
             <product_category id="196" name="Serial"/>
             <product_category id="198" name="SUN KVM"/>
             <product_category id="147" name="USB Adap">
                <product_category id="743" name="USB Adap"/>
                <product_category id="1040" name="USB Şarj Adap"/>
                <product_category id="1088" name="USB C Adap"/>
                <product_category id="1611" name="USB Seri Adap"/>
                <product_category id="1612" name="USB Ethernet Adap"/>
             </product_category>
            </product_category>
          </product_category>
       </product_category>
    </product_categories>

我想列出所有有父母ID的孩子和有自我ID的父母的列表。示例:


    Computer, [409]
      Server, [409,414]
        Multimedia Server, [409,414,511]
    Computer Equips, [97]
      Adaptor, [97,127]
        Audior, [97,127,133]
        ...
        ...
          USB Adap, [97,127,147,743]

我尝试解决我的问题好几个星期,但找不到解决方案? 如何使用ruby和nokogiri进行递归解析和转换?有任何建议。

1 个答案:

答案 0 :(得分:1)

这应该可以解决问题。它只是简单地遍历所有“ product_category”节点。对于每个节点,它获取祖先ID,然后打印名称和ID。

doc = Nokogiri::XML(open('test.xml'))
doc.search('product_category').each do |node|
  # get the current node's ID
  id = node.attr('id')

  # get all ancestor node IDs
  ancestor_ids = node.ancestors('product_category').map { |anode| anode.attr('id') }

  # put all the node IDs into an array
  all_ids = ([id] + ancestor_ids).reverse

  # output node name with all IDs and prepend spaces based on number of ancestors
  puts "#{'  ' * ancestor_ids.size}#{node.attr('name')}, [#{all_ids.join(', ')}]"
end

输出为:

Computer, [409]
  Server, [409, 414]
    Multimedia Server, [409, 414, 511]
  Server Equips, [409, 1645]
Computer Equips, [97]
  Adaptor, [97, 127]
    Audior, [97, 127, 133]
    DVI, [97, 127, 128]
    Firewire, [97, 127, 134]
    Gender Changer, [97, 127, 135]
    HDMI - DVI / DVI-I, [97, 127, 129]
    HDMI, [97, 127, 137]
    Keyboard, [97, 127, 139]
    Mouse, [97, 127, 141]
    Scart, [97, 127, 144]
    Serial, [97, 127, 196]
    SUN KVM, [97, 127, 198]
    USB Adap, [97, 127, 147]
      USB Adap, [97, 127, 147, 743]
      USB Şarj Adap, [97, 127, 147, 1040]
      USB C Adap, [97, 127, 147, 1088]
      USB Seri Adap, [97, 127, 147, 1611]
      USB Ethernet Adap, [97, 127, 147, 1612]