2015-02-20 11 views
5

kullanarak XML düğümü içeriğini değiştirmek nasıl. Bu, düğüm verilerinin nasıl değiştirileceğine değil, dosyaya nasıl geri kaydedileceğine dair bana açık değildir.varsa ben yeni bir değerle, tek bir düğümü bir XML belgesi okumak ve güncellemek için Ruby kullanıyorum Nokogiri

<?xml version="1.0" encoding="utf-8"> 
    <my_id>123</my_id> 
    <Route> 
     <To> 
     <Node> 
      <Filename>file1.txt</Filename> 
      <Filename>file2.mp3</Filename> 
      <Filename>file3.doc</Filename> 
      <Filename>file4.php</Filename> 
      <Filename>file5.jpg</Filename> 
     </Node> 
     </To> 
    </Route> 
</xml> 

Ben "file3.doc" den "file3_new.html" değiştirmek istiyorum:

def ammend_parent_xml(folder, target_file, new_file) 
    # open parent XML file that contains file reference 
    get_xml_files = Dir.glob("#{@target_folder}/#{folder}/*.xml").sort.select {|f| !File.directory? f} 
    get_xml_files.each { |xml| 

    f  = File.open(xml) 

    # Use Nokgiri to read the file into an XML object 
    doc  = Nokogiri::XML(f) 
    filename = doc.xpath('//Route//To//Node//FileName') 

    filename.each_with_index { 
     |fl, i| 
     if target_file == fl.text 
     # we found the file, now rename it to new_file 
     # ??????? 
     end 

    } 

    } 

end 

Bu

bazı örnek XML olduğunu.

Ben çağırır:

def ammend_parent_xml("folder_location", "file3.doc", "file3_new.html") 

cevap

3
def amend_parent_xml(folder, target_file, new_file) 
    Dir["#{@target_folder}/#{folder}/*.xml"] 
    .sort.select{|f| !File.directory? f } 
    .each do |xml_file| 
    doc = Nokogiri.XML(File.read(xml_file)) 
    if file = doc.at("//Route//To//Node//Filename[.='#{target_file}']") 
     file.content = new_file # set the text of the node 
     File.open(xml_file,'w'){ |f| f<<doc } 
     break 
    end 
    end 
end 

Geliştirmeler:

  • kullanın File.read yerine File.open bir dosya tanıtıcısı açık bırakmayın böylece

    Sonra içerik günceller.

  • doğru metin değerine sahip bir düğüm için bakarak TEK eşleşen düğümü bulmak için bir XPath ifadesi kullanır.
    • Alternatif tüm dosyaları bulabildiğim ve sonra if file=files.find{ |f| f.text==target_file }
  • geri diske bir Nokogiri::XML::Document seri hale getirilmeye gösterir.
  • Eşleşen bir XML dosyası bulur bulmaz dosyaları işlerken sonlandırır.
+1

OMG'ye biraz daha fazla bilgi ekledim, Pazartesi günü işe girmek için harika bir yol ... bu harika ve şimdi Nokogiri'nin nasıl çalıştığına birazcık daha bağlıyım! (ve şimdi de nasıl değiştirileceğini biliyorum: p) – Beertastic

2

XML bir öğe değiştirmek için:

file = File.new("xml_file.xml", "wb") 
file.write(@doc) 
file.close 

sizin örnek ile yanlış bir kaç şey vardır:

@doc = Nokogiri::XML::DocumentFragment.parse <<-EOXML 
<body> 
    <h1>OLD_CONTENT</h1> 
    <div>blah</div> 
</body> 
EOXML 


h1 = @doc.at_xpath "body/h1" 
h1.content = "NEW_CONTENT" 

puts @doc.to_xml #h1 will be NEW_CONTENT 

XML kaydetmek için XML.

  • iki kök elemanları my_id ve Route
  • birinci etiketinde ? eksik
  • Eğer son satırı </xml> var mi istiyorsunuz edilir vardır?

numunenin sabitlenmesi sonra Phrogz göre örnek kullanarak elemanını almak mümkün:

element = @doc.xpath("Route//To//Node//Filename[.='#{target_file}']").first 

Not .first bir nodeset döner çünkü.

element.content = "foobar" 
+0

Tamam ... benim örneğimde, kodunuzun hangi // Route // To // Node // FileName öğesinin güncelleneceğini nasıl bildiğimi ... XML'imde birkaç tane var, bu yüzden döngü yapıyorum bunların hepsi aracılığıyla – Beertastic

+0

Bir xml belgesinde belirli bir eleman arıyorsanız xpath kullanırdım.Örnek bir xml belgesi gönderir misiniz? – jmccure

+0

Eklenen XML örneği orijinal Soruya .. iyi fikir! – Beertastic

İlgili konular