当使用add_child时,nokogiri将更改节点属性

时间:2016-05-31 10:58:24

标签: android ruby nokogiri

这里是my full code,这是我的代码:

#!/usr/bin/env ruby
require 'nokogiri'

d = Nokogiri.parse(File.read(File.expand_path("../am.xml", __FILE__)))
perms = d.css('uses-permission')

d2 = Nokogiri.parse(File.read(File.expand_path("../am2.xml", __FILE__)))
d2.css('manifest')[0].add_child(perms)
puts d2

旧的

<uses-permission android:name="android.permission.INTERNET"/>

puts d2输出:

<uses-permission name="android.permission.INTERNET"/>

我希望puts d2输出“android:name =”,如何解决?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。我使用Node或NodeSet强制添加特定内容to_s

#!/usr/bin/env ruby
require 'ro_misc/exe'
include RoMisc::Exe

d = Nokogiri.parse(File.read(File.expand_path("../am.xml", __FILE__)))
perms = d.css('uses-permission')

d2 = Nokogiri.parse(File.read(File.expand_path("../am2.xml", __FILE__)))
d2.css('manifest')[0].add_child(perms.to_s)
puts d2

原因是,这种方法会改变属性包括&#34;:&#34;

  def add_child_node_and_reparent_attrs node # :nodoc:
    add_child_node node
    node.attribute_nodes.find_all { |a| a.name =~ /:/ }.each do |attr_node|
      attr_node.remove
      node[attr_node.name] = attr_node.value
    end
  end

原因是,Node#属性没有解析&#34; android:name&#34; as&#34; name&#34;。我重写Nokogiri::XML::Node#add_child_node_and_reparent_attrs,并使用正则表达式来解析节点属性:

  def add_child_node_and_reparent_attrs node # :nodoc:
    # here is a bug, if attr key is android:name, node.attribute_nodes will return name, so i should parse attrs by my self
    attrs = {}
    node.to_s.match(%r{<.*>}).to_s.scan(%r{(\S+)=(['"])(.*?)\2}) do |k, _, v|
      attrs[k] = v
    end

    add_child_node node

    attrs2 = node.attributes
    being_rm_attrs = (attrs2 - attrs)

    attrs2.each do |k, _|
      node.remove_attribute(k)
    end

    being_added_attrs = attrs - attrs2

    being_added_attrs.each do |k, v|
      node.set_attribute(k, v)
    end
    node
  end