xmlhash 1.2.4 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ === 1.3.0 / 2012-10-01
2
+
3
+ * parse will no longer return a plain ruby Hash, but a XMLHash,
4
+ which is a subclass with some convenience functions added to it
5
+
1
6
  === 1.2.4 / 2012-09-27
2
7
 
3
8
  * set the encoding of the result to the encoding of the input
@@ -1,4 +1,9 @@
1
1
  #include <assert.h>
2
+
3
+ /* libxml headers first - see https://github.com/coolo/xmlhash/issues/1 */
4
+ #include <libxml/parser.h>
5
+ #include <libxml/xmlreader.h>
6
+
2
7
  #include <ruby.h>
3
8
  #ifdef HAVE_RUBY_ST_H
4
9
  # include <ruby/st.h>
@@ -11,13 +16,11 @@
11
16
  # include <ruby/encoding.h>
12
17
  #endif
13
18
 
14
- #include <libxml/parser.h>
15
- #include <libxml/xmlreader.h>
16
-
17
19
  static VALUE m_current = Qnil;
18
20
  static VALUE m_stack = Qnil;
19
21
  static VALUE m_cstring = Qnil;
20
22
  static VALUE m_result = Qnil;
23
+ static VALUE m_xmlClass = Qnil;
21
24
  #ifdef HAVE_RUBY_ENCODING_H
22
25
  static rb_encoding *m_current_encoding = NULL;
23
26
  #endif
@@ -33,7 +36,7 @@ void xml_hash_start_element(const xmlChar *name)
33
36
  {
34
37
  VALUE pair;
35
38
  /* needed for further attributes */
36
- m_current = rb_hash_new();
39
+ m_current = rb_class_new_instance(0, 0, m_xmlClass);
37
40
  pair = rb_ary_new();
38
41
  rb_ary_push(pair, rb_str_new2((const char*)name));
39
42
  rb_ary_push(pair, m_current);
@@ -223,6 +226,7 @@ void Init_xmlhash()
223
226
 
224
227
  LIBXML_TEST_VERSION
225
228
  mXmlhash = rb_define_module("Xmlhash");
229
+ m_xmlClass = rb_define_class_under(mXmlhash, "XMLHash", rb_cHash);
226
230
  rb_define_singleton_method(mXmlhash, "parse", &parse_xml_hash, 1);
227
231
  m_stack = rb_ary_new();
228
232
  rb_global_variable(&m_stack);
Binary file
data/lib/xmlhash.rb CHANGED
@@ -1,5 +1,60 @@
1
1
  require 'xmlhash/xmlhash'
2
2
 
3
3
  module Xmlhash
4
- VERSION = '1.2.4'
4
+ VERSION = '1.3.0'
5
+
6
+ class XMLHash < Hash
7
+
8
+ # Return an array of elements or []. It requires a plain string as argument
9
+ #
10
+ # This makes it easy to write code that assumes an array.
11
+ # If there is just a single child in the XML, it will be wrapped
12
+ # in a single-elemnt array and if there are no children, an empty
13
+ # array is returned.
14
+ #
15
+ # You can also pass a block to iterate over all childrens.
16
+ def elements(name)
17
+ unless name.kind_of? String
18
+ raise ArgumentError, "expected string"
19
+ end
20
+ sub = self[name]
21
+ return [] unless sub
22
+ unless sub.kind_of? Array
23
+ if block_given?
24
+ yield sub
25
+ return
26
+ else
27
+ return [sub]
28
+ end
29
+ end
30
+ return sub unless block_given?
31
+ sub.each do |n|
32
+ yield n
33
+ end
34
+ end
35
+
36
+ # Return the element by the given name or an empty hash
37
+ #
38
+ # This makes it easy to write code that assumes a child to be present.
39
+ # obj["a"]["b"] will give you a "[] not defined for nil".
40
+ # obj.get("a")["b"] will give you nil
41
+ def get(name)
42
+ sub = self[name]
43
+ return sub if sub
44
+ return XMLHash.new
45
+ end
46
+
47
+ # Return the value of the name or nil if nothing is there
48
+ #
49
+ def value(name)
50
+ sub = self[name.to_s]
51
+ return nil unless sub
52
+ return '' if sub.empty? # avoid {}
53
+ return sub
54
+ end
55
+
56
+ def inspect
57
+ "X(#{super})"
58
+ end
59
+ end
5
60
  end
data/test/test_xmlhash.rb CHANGED
@@ -72,7 +72,7 @@ eos
72
72
  def test_entry
73
73
  xml = <<eos
74
74
  <?xml version='1.0' encoding='UTF-8'?>
75
- <directory>
75
+ <directory count="4">
76
76
  <entry name="Apache"/>
77
77
  <entry name="Apache:APR_Pool_Debug"/>
78
78
  <entry name="Apache:MirrorBrain"/>
@@ -80,15 +80,18 @@ eos
80
80
  </directory>
81
81
  eos
82
82
 
83
- rubyoutput = {"entry"=>
84
- [{"name"=>"Apache"},
85
- {"name"=>"Apache:APR_Pool_Debug"},
86
- {"name"=>"Apache:MirrorBrain"},
87
- {"name"=>"Apache:Modules"}]}
83
+ rubyoutput = {"count" => "4",
84
+ "entry"=>
85
+ [{"name"=>"Apache"},
86
+ {"name"=>"Apache:APR_Pool_Debug"},
87
+ {"name"=>"Apache:MirrorBrain"},
88
+ {"name"=>"Apache:Modules"}]}
89
+
90
+ ret = Xmlhash.parse(xml)
91
+ assert_equal ret, rubyoutput
92
+
93
+ assert_equal ret.elements("entry").first.value("name"), "Apache"
88
94
 
89
- ret = Xmlhash.parse(xml)
90
-
91
- assert_equal ret, rubyoutput
92
95
  end
93
96
 
94
97
  def test_encoding
@@ -100,6 +103,8 @@ eos
100
103
  xml = "<?xml version='1.0' encoding='UTF-8'?><name value='Adrian Schröter'/>"
101
104
  ret = Xmlhash.parse(xml)
102
105
  assert_equal ret, {"value"=>"Adrian Schröter"}
106
+
107
+ assert_equal ret.get("value"), "Adrian Schröter"
103
108
  end
104
109
 
105
110
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmlhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-27 00:00:00.000000000 Z
12
+ date: 2012-10-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pkg-config