Вы не можете поместить неэкранированный &
в XML, как хотите. Вот из W3 спецификации для XML :
Символ амперсанда (&) и левая угловая скобка (<) НЕ ДОЛЖНЫ появляться в их буквальной форме, за исключением случаев, когда они используются в качестве разделителей разметки или внутри комментария, инструкции по обработке или раздела CDATA. Если они нужны где-то еще, они ДОЛЖНЫ быть экранированы с использованием либо числовых ссылок на символы, либо строк «&» и «<» соответственно. </p>
Что касается использования CDATA в Nokogiri, вот информация с сайта Nokogiri, если вы используете Nokogiri :: XML :: Builder для создания своего XML.
ОБНОВЛЕНИЕ: Вот код из моего примера, упомянутого в комментариях.
module Questions
@source = File.dirname(__FILE__) + '/questions.xml'
def parse
if File.exists?(@source)
File.open(@source, 'r+') do |document|
q = {}
text = Nokogiri::XML::Document.parse(document)
text.xpath('.//question').each do |c|
parent = c.attribute_nodes[2].to_s
q[:type] = c.attribute_nodes[1].to_s.to_sym # => question type
q[:q_id] = c.attribute_nodes[0].to_s # => question type
q[:question] = c.xpath('.//q').first.content # => question
q[:answers] = []
c.xpath('.//a').each { |ans|
p = ans.attribute_nodes.first.value # => point value
a = ans.content # => answer
q[:answers] << [a, p]
}
if parent == "NA"
Question.create!(q)
else
Question.first(conditions: {q_id: parent}).children << Question.create!(q)
end
end
end
end
end
def write
builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
Question.each do |t|
xml.question(id: t.id, type: t.type, parent: t.parent) {
xml.q_ t.q
t.answers.each { |c|
xml.a(point: c.p) { xml.text c.a }
}
}
end
}
end
document = builder.to_xml
File.open(@source, 'w+') do |f|
f.puts document
end
end # end write
module_function :parse
module_function :write
end
--- И пример того, с чем я работал. ---
<question id="q0000" type="root" parent="NA">
<q>How do you feel about sports?</q>
<a point="0">I don't have any interest in sports.</a>
<a point="q0001">I like to play sports.</a>
<a point="q0002">I follow college or professional sports.</a>
</question>