From d18f1ac91f7d725ce58683b0dd845b33cb160ae8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sun, 14 Sep 2008 20:48:59 -0700 Subject: [PATCH] adding a method to set the root element of the document --- ext/nokogiri/xml_document.c | 19 +++++++++++++++++++ ext/nokogiri/xml_node.c | 9 +++++++-- lib/nokogiri.rb | 1 - lib/nokogiri/hpricot.rb | 6 ++++++ lib/nokogiri/xml/builder.rb | 14 ++++++++++++++ test/xml/test_document.rb | 16 ++++++++++++++++ 6 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 lib/nokogiri/xml/builder.rb diff --git a/ext/nokogiri/xml_document.c b/ext/nokogiri/xml_document.c index bc62ae5628..f3c49e52f5 100644 --- a/ext/nokogiri/xml_document.c +++ b/ext/nokogiri/xml_document.c @@ -24,6 +24,24 @@ static VALUE serialize(VALUE self) return rb_str; } +/* + * call-seq: + * root= + * + * Set the root element on this document + */ +static VALUE set_root(VALUE self, VALUE root) +{ + xmlDocPtr doc; + xmlNodePtr new_root; + + Data_Get_Struct(self, xmlDoc, doc); + Data_Get_Struct(root, xmlNode, new_root); + + xmlDocSetRootElement(doc, new_root); + return root; +} + /* * call-seq: * root @@ -107,6 +125,7 @@ void init_xml_document() rb_define_singleton_method(klass, "load_external_subsets=", load_external_subsets_set, 1); rb_define_method(klass, "root", root, 0); + rb_define_method(klass, "root=", set_root, 1); rb_define_method(klass, "serialize", serialize, 0); } diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 8c78aa2ade..d2fa4366e0 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -2,6 +2,9 @@ VALUE Nokogiri_wrap_xml_node(xmlNodePtr root) { + if(root->_private) + return (VALUE)root->_private; + VALUE klass = rb_eval_string("Nokogiri::XML::Node"); VALUE node = Data_Wrap_Struct(klass, NULL, NULL, root); root->_private = (void *)node; @@ -197,8 +200,7 @@ static VALUE document(VALUE self) static VALUE new(int argc, VALUE *argv, VALUE klass) { - VALUE name; - VALUE ns; + VALUE name, ns; xmlNsPtr xml_ns = NULL; rb_scan_args(argc, argv, "11", &name, &ns); @@ -209,6 +211,9 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) xmlNodePtr node = xmlNewNode(xml_ns, (xmlChar *)StringValuePtr(name)); VALUE rb_node = Data_Wrap_Struct(klass, NULL, NULL, node); node->_private = (void *)rb_node; + + if(rb_block_given_p()) rb_yield(rb_node); + return rb_node; } diff --git a/lib/nokogiri.rb b/lib/nokogiri.rb index 34eeaee2b0..9d4b6d67f9 100644 --- a/lib/nokogiri.rb +++ b/lib/nokogiri.rb @@ -5,7 +5,6 @@ require 'nokogiri/native' module Nokogiri - class << self def parse(string, url = nil, encoding = nil, options = 32) doc = diff --git a/lib/nokogiri/hpricot.rb b/lib/nokogiri/hpricot.rb index 79325d51d5..f40d43afbb 100644 --- a/lib/nokogiri/hpricot.rb +++ b/lib/nokogiri/hpricot.rb @@ -1,5 +1,6 @@ require 'nokogiri' +require 'nokogiri/xml/builder' module Nokogiri module XML @@ -13,6 +14,11 @@ def search(rule) end end +def Nokogiri(*args, &block) + builder = Nokogiri::XML::Builder.new + builder.instance_eval(&block) +end + module Nokogiri module Hpricot diff --git a/lib/nokogiri/xml/builder.rb b/lib/nokogiri/xml/builder.rb new file mode 100644 index 0000000000..8a839abe68 --- /dev/null +++ b/lib/nokogiri/xml/builder.rb @@ -0,0 +1,14 @@ +module Nokogiri + module XML + class Builder + def initialize + @doc = Nokogiri::XML::Document.new + end + + def method_missing(method, *args, &block) + node = Nokogiri::XML::Node.new(method.to_s) + node.content = args.first + end + end + end +end diff --git a/test/xml/test_document.rb b/test/xml/test_document.rb index 89832118da..09c927edae 100644 --- a/test/xml/test_document.rb +++ b/test/xml/test_document.rb @@ -47,6 +47,22 @@ def test_new assert doc.xml? assert_nil doc.root end + + def test_set_root + doc = nil + assert_nothing_raised { + doc = Nokogiri::XML::Document.new + } + assert doc + assert doc.xml? + assert_nil doc.root + node = Nokogiri::XML::Node.new("b") { |n| + n.content = 'hello world' + } + assert_equal('hello world', node.content) + doc.root = node + assert_equal(node, doc.root) + end end end end