Recently, I did a lot of work with Nokogiri to scrape web pages, however I also found Nokogiri very useful when generating XML documents.
In this post, I will show how to wrap data in a <![CDATA[]]> section when generating an XML document using Nokogiri. This is pretty simple to do, but I didn’t find any documentation explaining it. So, hopefully this will save someone else a few hours of hacking on this simple problem.
As a simple example, lets say that we wanted to describe a sandwich as an XML document that we generate with Nokogiri. Here’s the code:
require 'rubygems'
require 'nokogiri'
builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
xml.send(:sandwich,:xmlns => "http://www.davidrenz.net"){
xml.item(:type => :bread){
xml.attribute(){
xml.cdata "Whole Grain Wheat"
}
}
xml.item(:type => :meat){
xml.attribute(){
xml.cdata "Mesquite Tukey Breast"
}
}
xml.item(:type => :cheese){
xml.attribute(){
xml.cdata "Munster"
}
}
xml.item(:type => :condiment){
xml.attribute(){
xml.cdata "Tabasco Chipotle Sauce"
}
}
xml.item(:type => :topping){
xml.attribute(){
xml.cdata "Baby Spinach"
}
}
xml.item(:type => :topping){
xml.attribute{
xml.cdata "Sliced Avocado"
}
}
xml.item(:type => :topping){
xml.attribute("type"){
xml.cdata "Tomato"
}
}
}
end
Notice that all you need to do to create a CDATA section is to pass a string to the cdata method on the Builder object.
This is the XML generated calling to_xml on the Builder object.
<?xml version="1.0" encoding="utf-8"?>
<sandwich xmlns="http://www.davidrenz.net">
<item type="bread">
<attribute><![CDATA[Whole Grain Wheat]]></attribute>
</item>
<item type="meat">
<attribute><![CDATA[Mesquite Tukey Breast]]></attribute>
</item>
<item type="cheese">
<attribute><![CDATA[Munster]]></attribute>
</item>
<item type="condiment">
<attribute><![CDATA[Tabasco Chipotle Sauce]]></attribute>
</item>
<item type="topping">
<attribute><![CDATA[Baby Spinach]]></attribute>
</item>
<item type="topping">
<attribute><![CDATA[Sliced Avocado]]></attribute>
</item>
<item type="topping">
<attribute>type<![CDATA[Tomato]]></attribute>
</item>
</sandwich>
{ 0 comments }