2013-08-04 50 views
1

我有一個XML文檔:如何使用引入nokogiri的noblanks

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
</installation> 

我加入一個子節點到該文件是這樣的:

data = Nokogiri::XML(IO.read('file')) { |doc| doc.noblanks } 
new_record = Nokogiri::XML::Node.new('tag', data) 
data.root.add_child(new_record) 
File.open('file', 'w') { |dh_file| dh_file.write(data.to_xml(:indent => 4)) } 

有了這個代碼,我得到這個我的文件中:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
<tag/></installation> 

這裏的noblanks不起作用。 但是,如果之前插入新的節點我的文件已經有一個子節點,noblanks正常工作:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <!----> 
    <tag/> 
</installation> 

所以:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <!----> 
</installation> 

插入新節點之後:

插入新節點之前,它看起來像noblanks只有在它已經看到「模式」時才起作用。有沒有什麼辦法可以正確縮進我的XML,如果它沒有任何孩子呢?


也許noblanks是不使用正確的選擇,但由於某些原因,如果我已經有<installation>在某些節點工程。基本上我現在有添加子節點是這樣的時候:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
<tag/></installation> 

我需要的是這樣的:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <tag/> 
</installation> 

和子節點我想補充必須是空的,有一些屬性,我爲了簡單而被壓制

回答

0

你的兩個例子是迷茫的:它們都表現出完全相同的行爲,但你說其中一個做了一些不同的事情。

據我所知,指定noblanks從來沒有擺脫空節點:

xml.xml:

<?xml version="1.0"?> 
<root> 
    <installation id="ayfw-a"></installation> 
    <dog></dog> 
    <cat/> 
</root> 

require 'nokogiri' 

data = Nokogiri::XML(IO.read('xml.xml')) { |doc| doc.noblanks } 
puts data 

--output:-- 
<?xml version="1.0"?> 
<root> 
    <installation id="ayfw-a"/> 
    <dog/> 
    <cat/> 
</root> 

我希望可以將輸出爲:

<root> 
    <installation id="ayfw-a"></installation> 
</root> 

當然,可怕的引入nokogiri文檔(典型的Ruby)不定義一個空白點是什麼。顯然,什麼noblanks做的程度是轉換節點是這樣的:

<dog></dog> 

到:

<dog/> 

更新

啊,所以你的問題是你的XML漂亮的打印。好的,我看到了你所做的同樣的問題。讓我告訴你,你怎麼會問你的問題:


我無法格式化我的XML我想要的方式:

xml.xml:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
</installation> 

require 'nokogiri' 

data = Nokogiri::XML(IO.read('xml.xml')) {|doc| doc.noblanks} 
new_record = Nokogiri::XML::Node.new('tag', data) 
data.root.add_child(new_record) 
puts data.to_xml(indent: 4, indent_text: ".") 

--output:-- 
<?xml version="1.0"?> 
<installation id="ayfw-a"> 
<tag/></installation> 

to_xml()方法似乎不能正常工作。我預計輸出爲:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
....<tag/> 
</installation> 

to_xml()方法不格式化輸出我要當標籤具有預先存在的子節點的方式:

xml.xml:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <dog>Rover</dog> 
</installation> 

require 'nokogiri' 

data = Nokogiri::XML(IO.read('xml.xml')) {|doc| doc.noblanks} 
new_record = Nokogiri::XML::Node.new('tag', data) 
data.root.add_child(new_record) 
puts data.to_xml(indent: 4, indent_text: ".") 

--output:-- 
<?xml version="1.0"?> 
<installation id="ayfw-a"> 
....<dog>Rover</dog> 
....<tag/> 
</installation> 

我如何引入nokogiri格式化輸出我想在第一種情況下的方式嗎?


它看起來不像Nokogiri有一個非常漂亮的打印機。看來,REXML有一個更好的漂亮打印機比引入nokogiri:

xml.xml:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
</installation> 

require 'nokogiri' 

data = Nokogiri::XML(IO.read('xml.xml')) {|doc| doc.noblanks} 
new_record = Nokogiri::XML::Node.new('tag', data) 
data.root.add_child(new_record) 
puts data.to_xml(indent: 4, indent_text: ".") 

require "rexml/document" 

REXML::Document.new(data.to_xml).write(File.open("output.txt", "w"), indent_spaces = 4) 


--output:-- 
<installation id="ayfw-a"> 
<tag/></installation> 

$ cat output.txt 
<?xml version='1.0'?> 
<installation id='ayfw-a'> 
    <tag/> 
</installation> 
+0

我喜歡你的努力.. :)) –

+0

@Babai,謝謝! – 7stud

0

漂亮打印XML不是正確的XML的保證,它只是「漂亮」。 Nokogiri生成有效的XML,這非常重要。

如果你必須有一定的起動形式,創建一個小的模板引入nokogiri解析,那麼建立在它:

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <tag/> 
</installation> 
EOT 

puts doc.to_xml 

產生:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <tag/> 
</installation> 

調整代碼一點讓我設置開始root節點的ID和嵌入式標籤的名稱:

require 'nokogiri' 

ID = 'ayfw-a' 
TAG = 'foo' 

doc = Nokogiri::XML(<<EOT) 
<?xml version="1.0"?> 
<installation id="#{ ID }"> 
    <#{ TAG }/> 
</installation> 
EOT 

puts doc.to_xml 

個,輸出:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <foo/> 
</installation> 

寫這個的另一種方法是:

require 'nokogiri' 

ID = 'ayfw-a' 
TAG = 'foo' 

doc = Nokogiri::XML(<<EOT) 
<?xml version="1.0"?> 
<installation> 
    <tag/> 
</installation> 
EOT 

doc.root['id'] = ID 
doc.at('tag').name = TAG 

puts doc.to_xml 

,輸出:

<?xml version="1.0"?> 
<installation id="ayfw-a"> 
    <foo/> 
</installation> 

不管你做什麼,它可以讓你解決這個問題,併成爲生產力。