2011-12-06 31 views
17

Tôi hiện đang sử dụng lớp Nokogiri :: XML :: Builder để xây dựng một tài liệu XML, sau đó gọi .to_xml trên đó. Chuỗi kết quả luôn chứa một loạt các khoảng trống, các dòng dữ liệu và trả về vận chuyển giữa các nút, và tôi không thể cho cuộc sống của tôi tìm ra cách loại bỏ chúng. Dưới đây là một ví dụ:Nokogiri to_xml không có trả về vận chuyển

b = Nokogiri::XML::Builder.new do |xml| 
    xml.root do 
    xml.text("Value") 
    end 
end 

b.to_xml 

này kết quả trong những điều sau đây:

<?xml version="1.0"?> 
<root>Value</root> 

Những gì tôi muốn là thế này (chú ý xuống dòng mất tích):

<?xml version="1.0"?><root>Value</root> 

Làm thế nào điều này có thể được thực hiện? Cảm ơn trước!

Trả lời

29

Builder#to_xml theo kết quả đầu ra mặc định được định dạng (ví dụ: thụt lề) XML. Bạn có thể sử dụng số Nokogiri::XML::Node::SaveOptions để nhận được kết quả gần như không được định dạng.

b = Nokogiri::XML::Builder.new do |xml| 
    xml.root do 
    xml.foo do 
     xml.text("Value") 
    end 
    end 
end 

b.to_xml 
#=> "<?xml version=\"1.0\"?>\n<root>\n <foo>Value</foo>\n</root>\n" 

b.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML) 
#=> "<?xml version=\"1.0\"?>\n<root><foo>Value</foo></root>\n" 

Bây giờ bạn có thể hoặc chỉ thoát khỏi header XML (đó là tùy chọn anyway) và loại bỏ các newline cuối cùng

b.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip 
#=> "<root><foo>Value</foo></root>" 

Chỉ cần loại bỏ bất kỳ dòng mới trong XML có lẽ là một ý tưởng tồi như newlines thực sự có thể có ý nghĩa (ví dụ: trong số <pre> khối XHTML). Nếu đó không phải là trường hợp của bạn (và bạn thực sự chắc chắn về điều đó) bạn chỉ có thể làm điều đó.

+0

Thật không may là tôi đang mắc kẹt bằng cách sử dụng Nokogiri v1.3.3 mà không cho phép bất kỳ đối số được chuyển đến to_xml. Nếu không, đây sẽ là một giải pháp tuyệt vời. – Cameron

+1

Ah ok, hiểu rồi. Có vẻ như bạn có thể sử dụng phương pháp này bằng cách chuyển các tùy chọn lưu để tuần tự hóa thay vì to_xml: 'b.doc.serialize (: save_with => Nokogiri :: XML :: Node :: SaveOptions :: AS_XML)' – Cameron

+2

Giải pháp cuối cùng của tôi trông như thế này: 'builder.doc.serialize (: save_with => Nokogiri :: XML :: Node :: SaveOptions :: AS_XML) .sub (" \ n "," ") .strip' – Cameron

3

Đây không phải là điều mà Nokogiri được thiết kế để thực hiện. Gần nhất bạn có thể nhận được là để serialize thư mục gốc của tài liệu không có dòng mới hoặc thụt đầu dòng, và sau đó thêm PI mình (nếu bạn thực sự cần nó):

require 'nokogiri' 

b = Nokogiri::XML::Builder.new{ |xml| xml.root{ xml.foo "Value" } } 
p b.to_xml 
#=> "<?xml version=\"1.0\"?>\n<root>\n <foo>Value</foo>\n</root>\n" 

p b.doc.serialize(save_with:0) 
#=> "<?xml version=\"1.0\"?>\n<root><foo>Value</foo></root>\n" 

flat_root = b.doc.root.serialize(save_with:0) 
p flat_root 
#=> "<root><foo>Value</foo></root>" 

puts %Q{<?xml version="1.0"?>#{flat_root}} 
#=> <?xml version="1.0"?><root><foo>Value</foo></root> 

Ngoài ra, bạn chỉ có thể lừa gạt và làm:

puts b.doc.serialize(save_with:0).sub("\n","") 
#=> <?xml version="1.0"?><root><foo>Value</foo></root> 

Lưu ý việc sử dụng sub thay vì gsub chỉ thay thế các newline biết-Món quà đầu tiên.

+0

Giải pháp này gần giống với giải pháp được chấp nhận - cảm ơn! – Cameron

-1

b.to_xml trả về một chuỗi. Bạn chỉ cần thay thế phiên bản đầu tiên của \n trong chuỗi.

require 'nokogiri' 

b = Nokogiri::XML::Builder.new do |xml| 
    xml.root do 
    xml.text("Value") 
    end 
end 

b.to_xml.sub("\n",'') 

Có lẽ dễ hơn là cố gắng quá tải phương thức.

+2

Thay thế chỉ \ n đầu tiên sẽ không hoạt động - tài liệu tôi đang tạo ra thực sự là nhiều cấp độ sâu và mỗi nút có \ n sau đó. Một số văn bản trong các nút chứa \ n ký tự, mà tôi phải bảo toàn (đây là cho Android, yêu cầu các chuỗi kiểu Java). – Cameron

Các vấn đề liên quan