2016-05-31 3 views
-1

hier ist my full code, hier ist mein Code:nokogiri wird Knotenattribut ändern, wenn die Verwendung add_child

#!/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 

der alte ist

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

aber puts d2 Ausgang:

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

Ich hoffe, Ausgabe "android: name =", wie es zu beheben?

+0

Es ist nicht möglich, das Problem zu reproduzieren, weil Sie uns den Code nicht gegeben haben, für 'ro_misc' oder die XML-Dateien in _the Frage itself_. Bitte lesen Sie "[mcve]". Sie verwenden besser 'Nokogiri :: XML (File.open ('irgendeine Datei.xml'))' oder das HTML-Äquivalent, anstatt Nokogiri zu versuchen, zu entscheiden, ob es XML oder HTML ist. Ich habe gesehen, wie Nokogiri mit 'Nokogiri.parse' verwirrt wurde. –

+0

@theTinMan sorry, mein Code nicht ro_misc, ich habe mein Code aktualisieren – asullaherc

+0

Es ist immer noch nicht offensichtlich, was Sie zu tun versuchen. Vielleicht, wie "[mcve]" sagt, liefert die Eingabe der _minimal_ Eingabe-XML und Ihrer erwarteten Ausgabe XML. Lesen Sie die Links in "[Ask]", da sie Ihnen dabei helfen werden, nützliche Ideen und Tipps zu erfragen. –

Antwort

0

Ich fand die Lösung. Ich zwinge spezifischen zusätzlichen Inhalt mit Knoten oder 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 

Der Grund dafür ist, diese Methode es Attribut ändern ist „:“

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 

Der Grund dafür ist, Knoten # Attribut nicht analysieren "android: name" als "name". I außer Kraft setze Nokogiri::XML::Node#add_child_node_and_reparent_attrs und einen regulären Ausdruck verwenden, um das Knotenattribut zu analysieren:

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 
+0

Es ist gut, dass Sie eine Lösung gefunden haben, aber es ist sehr unwahrscheinlich, dass Sie tatsächlich eine Kernmethode für Nokogiri ändern müssen, um es zu tun. Ich habe viel Nokogiri-Code geschrieben und so etwas nie gebraucht. Wenn Sie eine Frage oder Antwort bearbeiten, fügen Sie bitte keine "Edit" - oder "Update" -Tags hinzu. SO hat eine Geschichte verfügbar, so dass wir jede Veränderung sehen können. Nehmen Sie stattdessen die Änderung so auf, als ob sie Teil des Originaltextes gewesen wäre. Siehe http://meta.stackoverflow.com/q/255644/128421 –

Verwandte Themen