nokogiri 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

@@ -1,3 +1,14 @@
1
+ === 1.2.3 / 2009年3月22日
2
+
3
+ * バグの修正
4
+
5
+ * Node#new 内にて、バグを修正する
6
+ * DocumentFragmentの作成時、名前空間に割り当てる LH #66
7
+ * Nokogiri::XML::NodeSet#dup は機能するようになった GH #10
8
+ * Nokogiri::HTMLは文字列がブランクの時、空のドキュメントで返す GH#11
9
+ * 子ノードを付加する事で、重複した名前空間の宣言を取り除く LH#67
10
+ * ビルダ方法はハッシュを第二引数とする
11
+
1
12
  === 1.2.2 / 2009年3月14日
2
13
 
3
14
  * 新しい機能
@@ -1,3 +1,14 @@
1
+ === 1.2.3 / 2009-03-22
2
+
3
+ * Bugfixes
4
+
5
+ * Fixing bug where a node is passed in to Node#new
6
+ * Namespace should be assigned on DocumentFragment creation. LH #66
7
+ * Nokogiri::XML::NodeSet#dup works GH #10
8
+ * Nokogiri::HTML returns an empty Document when given a blank string GH#11
9
+ * Adding a child will remove duplicate namespace declarations LH #67
10
+ * Builder methods take a hash as a second argument
11
+
1
12
  === 1.2.2 / 2009-03-14
2
13
 
3
14
  * New features
@@ -38,6 +38,11 @@ if Config::CONFIG['target_os'] == 'mingw32'
38
38
  unless find_header('iconv.h', header)
39
39
  abort "need iconv"
40
40
  end
41
+ else
42
+ unless find_header('iconv.h', INCLUDEDIR, '/opt/local/include',
43
+ '/usr/local/include', '/usr/include')
44
+ abort "iconv is missing. try 'port install iconv' or 'yum install iconv'"
45
+ end
41
46
  end
42
47
 
43
48
  xml2_dirs = dir_config('xml2', '/opt/local/include/libxml2', '/opt/local/lib')
@@ -12,6 +12,8 @@ static VALUE new(VALUE klass, VALUE doc)
12
12
  Data_Get_Struct(doc, xmlDoc, xml_doc);
13
13
 
14
14
  xmlNodePtr node = xmlNewDocFragment(xml_doc->doc);
15
+ if(node->doc->children)
16
+ node->ns = node->doc->children->ns;
15
17
 
16
18
  VALUE rb_node = Nokogiri_wrap_xml_node(node);
17
19
 
@@ -48,9 +48,19 @@ static VALUE reparent_node_with(VALUE node_obj, VALUE other_obj, node_other_func
48
48
  }
49
49
 
50
50
  // Make sure that our reparented node has the correct namespaces
51
- if(reparented->doc != reparented->parent)
51
+ if(reparented->doc != (xmlDocPtr)reparented->parent)
52
52
  reparented->ns = reparented->parent->ns;
53
53
 
54
+ // Search our parents for an existing definition
55
+ if(reparented->nsDef) {
56
+ xmlNsPtr ns = xmlSearchNsByHref(
57
+ reparented->doc,
58
+ reparented,
59
+ reparented->nsDef->href
60
+ );
61
+ if(ns) reparented->nsDef = NULL;
62
+ }
63
+
54
64
  reparented_obj = Nokogiri_wrap_xml_node(reparented);
55
65
 
56
66
  rb_funcall(reparented_obj, rb_intern("decorate!"), 0);
@@ -214,6 +224,30 @@ static VALUE replace(VALUE self, VALUE _new_node)
214
224
  return self ;
215
225
  }
216
226
 
227
+ /*
228
+ * call-seq:
229
+ * children
230
+ *
231
+ * Get the list of children for this node as a NodeSet
232
+ */
233
+ static VALUE children(VALUE self)
234
+ {
235
+ xmlNodePtr node;
236
+ Data_Get_Struct(self, xmlNode, node);
237
+
238
+ xmlNodePtr child = node->children;
239
+ xmlNodeSetPtr set = xmlXPathNodeSetCreate(child);
240
+
241
+ if(!child) return Nokogiri_wrap_xml_node_set(set);
242
+
243
+ child = child->next;
244
+ while(NULL != child) {
245
+ xmlXPathNodeSetAdd(set, child);
246
+ child = child->next;
247
+ }
248
+
249
+ return Nokogiri_wrap_xml_node_set(set);
250
+ }
217
251
 
218
252
  /*
219
253
  * call-seq:
@@ -590,7 +624,7 @@ static VALUE new(VALUE klass, VALUE name, VALUE document)
590
624
  Data_Get_Struct(document, xmlDoc, doc);
591
625
 
592
626
  xmlNodePtr node = xmlNewNode(NULL, (xmlChar *)StringValuePtr(name));
593
- node->doc = doc;
627
+ node->doc = doc->doc;
594
628
 
595
629
  VALUE rb_node = Nokogiri_wrap_xml_node(node);
596
630
 
@@ -630,19 +664,21 @@ VALUE Nokogiri_wrap_xml_node(xmlNodePtr node)
630
664
  VALUE node_cache = Qnil ;
631
665
  VALUE rb_node = Qnil ;
632
666
 
633
- if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
634
- document = DOC_RUBY_OBJECT(node->doc);
635
- node_cache = rb_funcall(document, rb_intern("node_cache"), 0);
636
- rb_node = rb_hash_aref(node_cache, index);
637
- if(rb_node != Qnil) return rb_node;
638
- }
667
+ if(node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE)
668
+ return DOC_RUBY_OBJECT(node->doc);
669
+
670
+ if(NULL != node->_private) return (VALUE)node->_private;
639
671
 
640
672
  switch(node->type)
641
673
  {
642
674
  VALUE klass;
643
675
 
676
+ case XML_ELEMENT_NODE:
677
+ klass = cNokogiriXmlElement;
678
+ rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
679
+ break;
644
680
  case XML_TEXT_NODE:
645
- klass = rb_const_get(mNokogiriXml, rb_intern("Text"));
681
+ klass = cNokogiriXmlText;
646
682
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
647
683
  break;
648
684
  case XML_ENTITY_REF_NODE:
@@ -661,10 +697,6 @@ VALUE Nokogiri_wrap_xml_node(xmlNodePtr node)
661
697
  klass = cNokogiriXmlProcessingInstruction;
662
698
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
663
699
  break;
664
- case XML_ELEMENT_NODE:
665
- klass = rb_const_get(mNokogiriXml, rb_intern("Element"));
666
- rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
667
- break;
668
700
  case XML_ATTRIBUTE_NODE:
669
701
  klass = cNokogiriXmlAttr;
670
702
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
@@ -681,17 +713,21 @@ VALUE Nokogiri_wrap_xml_node(xmlNodePtr node)
681
713
  klass = rb_const_get(mNokogiriXml, rb_intern("DTD"));
682
714
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
683
715
  break;
684
- case XML_DOCUMENT_NODE:
685
- return DOC_RUBY_OBJECT(node->doc);
686
- case XML_HTML_DOCUMENT_NODE:
687
- return DOC_RUBY_OBJECT(node->doc);
688
716
  default:
689
717
  rb_node = Data_Wrap_Struct(cNokogiriXmlNode, 0, debug_node_dealloc, node) ;
690
718
  }
691
719
 
720
+ node->_private = (void *)rb_node;
721
+
722
+ if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
723
+ document = DOC_RUBY_OBJECT(node->doc);
724
+ node_cache = rb_funcall(document, rb_intern("node_cache"), 0);
725
+ }
726
+
692
727
  if (node_cache != Qnil) rb_hash_aset(node_cache, index, rb_node);
693
728
  rb_iv_set(rb_node, "@document", document);
694
729
  rb_funcall(rb_node, rb_intern("decorate!"), 0);
730
+
695
731
  return rb_node ;
696
732
  }
697
733
 
@@ -748,6 +784,8 @@ void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
748
784
 
749
785
 
750
786
  VALUE cNokogiriXmlNode ;
787
+ VALUE cNokogiriXmlElement ;
788
+
751
789
  void init_xml_node()
752
790
  {
753
791
  VALUE nokogiri = rb_define_module("Nokogiri");
@@ -756,6 +794,8 @@ void init_xml_node()
756
794
 
757
795
  cNokogiriXmlNode = klass;
758
796
 
797
+ cNokogiriXmlElement = rb_define_class_under(xml, "Element", klass);
798
+
759
799
  rb_define_singleton_method(klass, "new", new, 2);
760
800
 
761
801
  rb_define_method(klass, "add_namespace", add_namespace, 2);
@@ -764,6 +804,7 @@ void init_xml_node()
764
804
  rb_define_method(klass, "add_child", add_child, 1);
765
805
  rb_define_method(klass, "parent", get_parent, 0);
766
806
  rb_define_method(klass, "child", child, 0);
807
+ rb_define_method(klass, "children", children, 0);
767
808
  rb_define_method(klass, "next_sibling", next_sibling, 0);
768
809
  rb_define_method(klass, "previous_sibling", previous_sibling, 0);
769
810
  rb_define_method(klass, "node_type", node_type, 0);
@@ -7,6 +7,8 @@ void init_xml_node();
7
7
  VALUE Nokogiri_wrap_xml_node(xmlNodePtr root);
8
8
 
9
9
  extern VALUE cNokogiriXmlNode ;
10
+ extern VALUE cNokogiriXmlElement ;
11
+
10
12
  VALUE Nokogiri_wrap_xml_node(xmlNodePtr node) ;
11
13
  void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_hash) ;
12
14
  void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash) ;
@@ -1,5 +1,26 @@
1
1
  #include <xml_node_set.h>
2
2
  #include <libxml/xpathInternals.h>
3
+
4
+ /*
5
+ * call-seq:
6
+ * dup
7
+ *
8
+ * Duplicate this node set
9
+ */
10
+ static VALUE dup(VALUE self)
11
+ {
12
+ xmlNodeSetPtr node_set;
13
+ Data_Get_Struct(self, xmlNodeSet, node_set);
14
+
15
+ xmlNodeSetPtr dupl = xmlXPathNodeSetCreate(NULL);
16
+ int i;
17
+ for(i = 0; i < node_set->nodeNr; i++) {
18
+ xmlXPathNodeSetAdd(dupl, node_set->nodeTab[i]);
19
+ }
20
+
21
+ return Nokogiri_wrap_xml_node_set(dupl);
22
+ }
23
+
3
24
  /*
4
25
  * call-seq:
5
26
  * length
@@ -58,6 +79,34 @@ static VALUE index_at(VALUE self, VALUE number)
58
79
  return Nokogiri_wrap_xml_node(node_set->nodeTab[i]);
59
80
  }
60
81
 
82
+ /*
83
+ * call-seq:
84
+ * to_a
85
+ *
86
+ * Return this list as an Array
87
+ */
88
+ static VALUE to_array(VALUE self, VALUE rb_node)
89
+ {
90
+ xmlNodeSetPtr set;
91
+ Data_Get_Struct(self, xmlNodeSet, set);
92
+
93
+ VALUE *elts = calloc((size_t)set->nodeNr, sizeof(VALUE *));
94
+ int i;
95
+ for(i = 0; i < set->nodeNr; i++) {
96
+ if(set->nodeTab[i]->_private) {
97
+ elts[i] = (VALUE)set->nodeTab[i]->_private;
98
+ } else {
99
+ elts[i] = Nokogiri_wrap_xml_node(set->nodeTab[i]);
100
+ }
101
+ }
102
+
103
+ VALUE list = rb_ary_new4(set->nodeNr, elts);
104
+
105
+ free(elts);
106
+
107
+ return list;
108
+ }
109
+
61
110
  /*
62
111
  * call-seq:
63
112
  * unlink
@@ -145,4 +194,6 @@ void init_xml_node_set(void)
145
194
  rb_define_method(klass, "[]", index_at, 1);
146
195
  rb_define_method(klass, "push", push, 1);
147
196
  rb_define_method(klass, "unlink", unlink_nodeset, 0);
197
+ rb_define_method(klass, "to_a", to_array, 0);
198
+ rb_define_method(klass, "dup", dup, 0);
148
199
  }
@@ -38,6 +38,7 @@ module Nokogiri
38
38
  return Document.read_io(string_or_io, url, encoding, options)
39
39
  end
40
40
 
41
+ return Document.new if(string_or_io.length == 0)
41
42
  Document.read_memory(string_or_io, url, encoding, options)
42
43
  end
43
44
 
@@ -1,4 +1,4 @@
1
1
  module Nokogiri
2
2
  # The version of Nokogiri you are using
3
- VERSION = '1.2.2'
3
+ VERSION = '1.2.3'
4
4
  end
@@ -2,7 +2,7 @@ module Nokogiri
2
2
  module XML
3
3
  class Builder
4
4
  attr_accessor :doc, :parent, :context
5
- def initialize(&block)
5
+ def initialize &block
6
6
  namespace = self.class.name.split('::')
7
7
  namespace[-1] = 'Document'
8
8
  @doc = eval(namespace.join('::')).new
@@ -15,13 +15,13 @@ module Nokogiri
15
15
  @parent = @doc
16
16
  end
17
17
 
18
- def text(string)
19
- node = Nokogiri::XML::Text.new(string, @doc)
18
+ def text string
19
+ node = Nokogiri::XML::Text.new(string.to_s, @doc)
20
20
  insert(node)
21
21
  end
22
22
 
23
- def cdata(string)
24
- node = Nokogiri::XML::CDATA.new(@doc, string)
23
+ def cdata string
24
+ node = Nokogiri::XML::CDATA.new(@doc, string.to_s)
25
25
  insert(node)
26
26
  end
27
27
 
@@ -29,16 +29,17 @@ module Nokogiri
29
29
  @doc.to_xml
30
30
  end
31
31
 
32
- def method_missing(method, *args, &block)
32
+ def method_missing method, *args, &block
33
33
  if @context && @context.respond_to?(method)
34
34
  @context.send(method, *args, &block)
35
35
  else
36
36
  node = Nokogiri::XML::Node.new(method.to_s, @doc) { |n|
37
- if content = args.first
38
- if content.is_a?(Hash)
39
- content.each { |k,v| n[k.to_s] = v.to_s }
37
+ args.each do |arg|
38
+ case arg
39
+ when Hash
40
+ arg.each { |k,v| n[k.to_s] = v.to_s }
40
41
  else
41
- n.content = content
42
+ n.content = arg
42
43
  end
43
44
  end
44
45
  }
@@ -65,22 +65,6 @@ module Nokogiri
65
65
  document.decorate(self) if document
66
66
  end
67
67
 
68
- ###
69
- # Get the list of children for this node as a NodeSet
70
- def children
71
- list = NodeSet.new(document)
72
- document.decorate(list)
73
-
74
- first = self.child
75
- return list unless first # Empty list
76
-
77
- list << first
78
- while first = first.next
79
- list << first
80
- end
81
- list
82
- end
83
-
84
68
  ###
85
69
  # Search this node for +paths+. +paths+ can be XPath or CSS, and an
86
70
  # optional hash of namespaces may be appended.
@@ -305,7 +289,7 @@ module Nokogiri
305
289
  ####
306
290
  # Set the content to +string+.
307
291
  def content= string
308
- self.native_content = encode_special_chars(string)
292
+ self.native_content = encode_special_chars(string.to_s)
309
293
  end
310
294
 
311
295
  ###
@@ -136,10 +136,8 @@ module Nokogiri
136
136
  ###
137
137
  # Iterate over each node, yielding to +block+
138
138
  def each(&block)
139
- x = 0
140
- while x < length
139
+ 0.upto(length - 1) do |x|
141
140
  yield self[x]
142
- x += 1
143
141
  end
144
142
  end
145
143
 
@@ -14,11 +14,12 @@ module XSD
14
14
  #
15
15
  # require 'rubygems'
16
16
  # gem 'soap4r'
17
+ # require 'nokogiri'
17
18
  # require 'xsd/xmlparser/nokogiri'
18
19
  # require 'defaultDriver'
19
20
  #
20
21
  # obj = AvlPortType.new
21
- # obj.getLatestByRout(obj.getAgencies, 8).each do |event|
22
+ # obj.getLatestByRoute(obj.getAgencies, 8).each do |event|
22
23
  # ...
23
24
  # end
24
25
  class Nokogiri < XSD::XMLParser::Parser
@@ -3,6 +3,18 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
3
3
  module Nokogiri
4
4
  module HTML
5
5
  class TestBuilder < Nokogiri::TestCase
6
+ def test_builder_with_explicit_tags
7
+ html_doc = Nokogiri::HTML::Builder.new {
8
+ div.slide(:class => 'another_class') {
9
+ node = Nokogiri::XML::Node.new("id", doc)
10
+ node.content = "hello"
11
+ insert(node)
12
+ }
13
+ }.doc
14
+ assert_equal 1, html_doc.css('div.slide > id').length
15
+ assert_equal 'hello', html_doc.at('div.slide > id').content
16
+ end
17
+
6
18
  def test_hash_as_attributes_for_attribute_method
7
19
  html = Nokogiri::HTML::Builder.new {
8
20
  div.slide(:class => 'another_class') {
@@ -22,6 +34,17 @@ module Nokogiri
22
34
  builder.doc.root.to_html.gsub(/\n/, '').gsub(/>\s*</, '><'))
23
35
  end
24
36
 
37
+ def test_href_with_attributes
38
+ uri = 'http://tenderlovemaking.com/'
39
+ built = Nokogiri::XML::Builder.new { |x|
40
+ div {
41
+ a('King Khan & The Shrines', :href => uri)
42
+ }
43
+ }
44
+ assert_equal 'http://tenderlovemaking.com/',
45
+ built.doc.at('a')[:href]
46
+ end
47
+
25
48
  def test_tag_nesting
26
49
  builder = Nokogiri::HTML::Builder.new do
27
50
  span.left ''
@@ -8,6 +8,10 @@ module Nokogiri
8
8
  @html = Nokogiri::HTML.parse(File.read(HTML_FILE))
9
9
  end
10
10
 
11
+ def test_emtpy_string_returns_empty_doc
12
+ doc = Nokogiri::HTML('')
13
+ end
14
+
11
15
  def test_swap_should_not_exist
12
16
  assert_raises(NoMethodError) {
13
17
  @html.swap
@@ -10,6 +10,50 @@ module Nokogiri
10
10
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
11
11
  end
12
12
 
13
+ def test_duplicate_node_removes_namespace
14
+ fruits = Nokogiri::XML(<<-eoxml)
15
+ <Fruit xmlns='www.fruits.org'>
16
+ <Apple></Apple>
17
+ </Fruit>
18
+ eoxml
19
+ apple = fruits.root.xpath('fruit:Apple', {'fruit'=>'www.fruits.org'})[0]
20
+ new_apple = apple.dup
21
+ fruits.root << new_apple
22
+ assert_equal 2, fruits.xpath('//xmlns:Apple').length
23
+ assert_equal 1, fruits.to_xml.scan('www.fruits.org').length
24
+ end
25
+
26
+ def test_node_added_to_root_should_get_namespace
27
+ fruits = Nokogiri::XML(<<-eoxml)
28
+ <Fruit xmlns='http://www.fruits.org'>
29
+ </Fruit>
30
+ eoxml
31
+ apple = fruits.fragment('<Apple/>')
32
+ fruits << apple
33
+ assert_equal 1, fruits.xpath('//xmlns:Apple').length
34
+ end
35
+
36
+ def test_add_child_path_following_sequential_text_nodes
37
+ xml = Nokogiri::XML('<root>text</root>')
38
+ xml.root.add_child(Nokogiri::XML::Text.new('text', xml))
39
+ item = xml.root.add_child(Nokogiri::XML::Element.new('item', xml))
40
+ assert_equal '/root/item', item.path
41
+ end
42
+
43
+ def test_children
44
+ doc = Nokogiri::XML(<<-eoxml)
45
+ <root>#{'<a/>' * 9 }</root>
46
+ eoxml
47
+ assert_equal 9, doc.root.children.length
48
+ assert_equal 9, doc.root.children.to_a.length
49
+
50
+ doc = Nokogiri::XML(<<-eoxml)
51
+ <root>#{'<a/>' * 15 }</root>
52
+ eoxml
53
+ assert_equal 15, doc.root.children.length
54
+ assert_equal 15, doc.root.children.to_a.length
55
+ end
56
+
13
57
  def test_add_namespace
14
58
  node = @xml.at('address')
15
59
  node.add_namespace('foo', 'http://tenderlovemaking.com')
@@ -192,6 +236,12 @@ module Nokogiri
192
236
  assert_match 'hello', xml.to_s
193
237
  end
194
238
 
239
+ def test_set_content_with_symbol
240
+ node = @xml.at('//name')
241
+ node.content = :foo
242
+ assert_equal 'foo', node.content
243
+ end
244
+
195
245
  def test_add_previous_sibling
196
246
  xml = Nokogiri::XML(<<-eoxml)
197
247
  <root>
@@ -8,6 +8,15 @@ module Nokogiri
8
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
9
9
  end
10
10
 
11
+ def test_dup
12
+ assert node_set = @xml.xpath('//employee')
13
+ dup = node_set.dup
14
+ assert_equal node_set.length, dup.length
15
+ node_set.zip(dup).each do |a,b|
16
+ assert_equal a, b
17
+ end
18
+ end
19
+
11
20
  def test_xmlns_is_automatically_registered
12
21
  doc = Nokogiri::XML(<<-eoxml)
13
22
  <root xmlns="http://tenderlovemaking.com/">
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nokogiri
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-03-14 00:00:00 -07:00
13
+ date: 2009-03-22 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency