Add CData Sections to XML Documents Generated in Ruby with Nokogiri

April 21, 2011

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>

Leave a Comment

Previous post: