Nokogiri to_xml zonder carriage return

Ik gebruik momenteel de klasse Nokogiri :: xml :: Builder om een ​​XML-document te maken en vervolgens .to_xml erop aan te roepen. De resulterende string bevat altijd een hoop spaties, linefeeds en carriage returns tussen de knooppunten, en ik kan niet voor het leven van me achterhalen hoe ik van ze af kan komen. Hier is een voorbeeld:

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

b.to_xml

Dit resulteert in het volgende:

<?xml version="1.0"?>
Value

Wat ik wil is dit (let op de ontbrekende newline):

<?xml version="1.0"?>Value

Hoe kan dit worden gedaan? Bij voorbaat dank!

18

3 antwoord

Builder#to_xml by default outputs formatted (i.e. indented) XML. You can use the Nokogiri::XML::Node::SaveOptions to get an almost unformatted result.

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\n  Value\n\n"

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

Nu kunt u ofwel de XML-header (die toch optioneel is) verwijderen en de laatste nieuwe regel verwijderen

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

Just removing any newlines in the xml is probably a bad idea as newlines can actually be significant (e.g. in

 blocks of XHTML). If that is not the case for you (and you are really sure of that) you could just do it.

30
toegevoegd
Helaas zit ik vast met het gebruik van Nokogiri v1.3.3, waardoor geen argumenten kunnen worden doorgegeven aan to_xml. Anders zou dit een geweldige oplossing zijn.
toegevoegd de auteur Cameron, de bron
Ah ok, snap het. Het lijkt erop dat u deze methode kunt gebruiken door de opslagopties door te geven in serialize in plaats van to_xml: b.doc.serialize (: save_with => Nokogiri :: xml :: Node :: SaveOptions :: AS_XML)
toegevoegd de auteur Cameron, de bron
Mijn definitieve oplossing ziet er zo uit: builder.doc.serialize (: save_with => Nokogiri :: xml :: Node :: SaveOptions :: AS_XML) .sub ("\ n", "") .strip
toegevoegd de auteur Cameron, de bron

Dit is niet iets waarvoor Nokogiri is ontworpen. Het dichtst dat je kunt krijgen is om de root van het document te serialiseren zonder nieuwe regels of inspringen, en dan de PI zelf toe te voegen (als je het echt nodig hebt):

require 'nokogiri'

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

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

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

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

Je kunt ook gewoon vals spelen en doen:

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

Let op het gebruik van sub in plaats van gsub om alleen de eerste bekende nieuwe regel te vervangen.

3
toegevoegd
Deze oplossing is bijna hetzelfde als de geaccepteerde oplossing - bedankt!
toegevoegd de auteur Cameron, de bron

b.to_xml returns a string. You just need to replace the first instance of \n in the string.

require 'nokogiri'

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

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

Waarschijnlijk eenvoudiger dan de methode te overbelasten.

1
toegevoegd
Alleen de eerste vervangen \ n werkt niet - het document dat ik aan het maken ben is vele niveaus diep en elk knooppunt heeft er een \ n erna. Sommige van de tekst in de knooppunten bevat ook \ n tekens, die ik moet behouden (dit is voor Android, waarvoor tekenreeksen in Java-stijl vereist zijn).
toegevoegd de auteur Cameron, de bron