2011-12-06 22 views
17

Actualmente estoy usando la clase Nokogiri :: XML :: Builder para construir un documento XML y luego llamarlo a .to_xml. La cadena resultante siempre contiene un grupo de espacios, avances de línea y retornos de carro entre los nodos, y no puedo saber cómo deshacerme de ellos. He aquí un ejemplo:Nokogiri to_xml sin retorno de carro

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

b.to_xml 

El resultado es la siguiente:

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

Lo que quiero es esto (nota la nueva línea que falta):

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

¿Cómo puede hacerse esto? ¡Gracias por adelantado!

Respuesta

29

Builder#to_xml salidas predeterminadas formateadas (es decir, sangradas) XML. Puede usar el Nokogiri::XML::Node::SaveOptions para obtener un resultado casi sin formato.

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" 

Ahora usted podría ya sea simplemente deshacerse de la cabecera XML (que es opcional en cualquier caso) y retire el último salto de línea

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

sólo la eliminación de cualquier saltos de línea en el XML es probablemente una mala idea ya que las nuevas líneas en realidad puede ser significativo (por ejemplo, en <pre> bloques de XHTML). Si ese no es el caso para ti (y estás realmente seguro de eso) podrías hacerlo.

+0

Desafortunadamente estoy atrapado usando Nokogiri v1.3.3 que no permite que ningún argumento pase a to_xml. De lo contrario, esta sería una gran solución. – Cameron

+1

Ah ok, lo tengo. Parece que puede usar este método pasando las opciones de guardado para serializar en lugar de to_xml: 'b.doc.serialize (: save_with => Nokogiri :: XML :: Node :: SaveOptions :: AS_XML)' – Cameron

+2

Mi solución final se ve así: 'builder.doc.serialize (: save_with => Nokogiri :: XML :: Node :: SaveOptions :: AS_XML) .sub (" \ n "," ") .strip' – Cameron

3

Esto no es algo que Nokogiri está diseñado para hacer. Lo más cerca que se puede obtener es serializar la raíz del documento, sin saltos de línea o sangría y, a continuación, añadir el PI sí mismo (si realmente lo necesita):

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> 

Como alternativa, simplemente puede engañar y hacer:

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

Nota el uso de sub en lugar de gsub sustituir sólo el primer salto de línea conocida presente.

+0

Esta solución es casi la misma que la aceptada, ¡gracias! – Cameron

-1

b.to_xml devuelve una cadena. Solo necesita reemplazar la primera instancia de \n en la cadena.

require 'nokogiri' 

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

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

Probablemente más fácil que intentar sobrecargar el método.

+2

Reemplazar solo el primero \ n no funcionará - el documento que estoy creando tiene muchos niveles de profundidad, y cada nodo tiene \ n después de él. Parte del texto en los nodos también contiene \ n caracteres, que debo conservar (esto es para Android, que requiere cadenas de estilo Java). – Cameron

Cuestiones relacionadas