ox 2.13.4 → 2.14.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 455a3e6630c8cf482656e024c14c609cfcc5441d201dd6b6f7649a283309bf87
4
- data.tar.gz: e6240807c3f21f2915d044b56bc05433730a39315b10a50c3698adcc5640cf1d
3
+ metadata.gz: 8bef5b070b17c09cb705e4a6f9b89f7de94c32d426057261cc2c763f10217fa8
4
+ data.tar.gz: e79898f9f7100fe30c99bbb111d52098316e19422afe47f91721f1de36aa5c0b
5
5
  SHA512:
6
- metadata.gz: 3ddfd3e2a3e80338a1f5d4cf36b9b0ea28b721f24d7d6bc8c3b1a27c2c026484596274b105b4da602e4070627411297295807eebbf83cc923863d4494e0c0c32
7
- data.tar.gz: af3b468beb6e48aa6046b3829ee186433be56d308dd3bb06b19068eefd4a315c004353aaa245a95fdc42d315e817d7cca4f3d309b745fb782c5e77bbd463e427
6
+ metadata.gz: e1079d0bd17806632a2eea08ec38e78baba5262af6b5ec58c434bf1bc2520fad6850680a6cb53a1e1dac67b175de3487f639d75e19b76cbeb9960bdd1db5e4b9
7
+ data.tar.gz: 941904c648314466f078c72a8004cb0f5da2e39ca5883485f1af8b4daf698d6bf528f38e4c84bc056ad01e7fa6c5333ff26a8665acf3af932c51ede5ef40c0f6
data/CHANGELOG.md CHANGED
@@ -2,7 +2,36 @@
2
2
 
3
3
  All changes to the Ox gem are documented here. Releases follow semantic versioning.
4
4
 
5
- ## [Unreleased]
5
+ ## [2.14.4] - 2021-03-19
6
+
7
+ ### Fixed
8
+
9
+ - Really fixed code issue around HAVE_RB_ENC_ASSOCIATE.
10
+
11
+ ## [2.14.3] - 2021-03-12
12
+
13
+ ### Fixed
14
+
15
+ - Code issue around HAVE_RB_ENC_ASSOCIATE fixed.
16
+
17
+ ## [2.14.2] - 2021-03-07
18
+
19
+ ### Fixed
20
+
21
+ - Attribute keys for setting attributes no longer create seemily
22
+ duplicates if symbol and string keys are mixed.
23
+
24
+ ## [2.14.1] - 2021-01-11
25
+
26
+ ### Fixed
27
+
28
+ - In Ruby 3.0 Range objects are frozen. This version allows Ranges to be created on load.
29
+
30
+ ## [2.14.0] - 2020-12-15
31
+
32
+ ### Added
33
+
34
+ - The `:with_cdata` option added for the hash_load() function.
6
35
 
7
36
  ## [2.13.4] - 2020-09-11
8
37
 
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Ox gem
2
2
  A fast XML parser and Object marshaller as a Ruby gem.
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/ohler55/ox.svg?branch=master)](http://travis-ci.org/ohler55/ox) [![TideLift](https://tidelift.com/badges/github/ohler55/ox)](https://tidelift.com/subscription/pkg/rubygems-ox?utm_source=rubygems-ox&utm_medium=referral&utm_campaign=readme)
5
- [![Financial Contributors on Open Collective](https://opencollective.com/ohler/all/badge.svg?label=financial+contributors)](https://opencollective.com/ohler)
4
+ [![Build status](https://ci.appveyor.com/api/projects/status/pg2w4wspbrflbi8c?svg=true)](https://ci.appveyor.com/project/ohler55/ox)
6
5
 
7
6
  ## Installation
8
7
  gem install ox
@@ -17,10 +16,6 @@ A fast XML parser and Object marshaller as a Ruby gem.
17
16
 
18
17
  *RubyGems* *repo*: https://rubygems.org/gems/ox
19
18
 
20
- ## Follow @oxgem on Twitter
21
-
22
- [Follow @peterohler on Twitter](http://twitter.com/#!/peterohler) for announcements and news about the Ox gem.
23
-
24
19
  ## Support
25
20
 
26
21
  [Get supported Ox with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-ox?utm_source=rubygems-ox&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
@@ -79,7 +74,7 @@ callbacks. Unlike Nokogiri and LibXML, Ox can be tuned to use only the SAX
79
74
  callbacks that are of interest to the caller. (See the perf_sax.rb file for an
80
75
  example.)
81
76
 
82
- Ox is compatible with Ruby 1.8.7, 1.9.3, 2.1.2, 2.2.0 and RBX.
77
+ Ox is compatible with Ruby 2.3, 2.4, 2.5, 2.6, 2.7, 3.0.
83
78
 
84
79
  ### Object Dump Sample:
85
80
 
data/ext/ox/dump.c CHANGED
@@ -838,7 +838,7 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
838
838
  out->w_start(out, &e);
839
839
 
840
840
  for (i = 0; i < cnt; i++) {
841
- VALUE v = RSTRUCT_GET(obj, i);
841
+ VALUE v = RSTRUCT_GET(obj, (int)(i));
842
842
  dump_obj(rb_intern(ulong2str(i, num_buf + sizeof(num_buf) - 1)), v, d2, out);
843
843
  }
844
844
  out->w_end(out, &e);
data/ext/ox/gen_load.c CHANGED
@@ -116,18 +116,18 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
116
116
  #endif
117
117
  rb_hash_aset(ah, sym, rb_str_new2(attrs->value));
118
118
  } else {
119
+ #if HAVE_RB_ENC_ASSOCIATE
119
120
  volatile VALUE rstr = rb_str_new2(attrs->name);
120
121
 
121
- #if HAVE_RB_ENC_ASSOCIATE
122
122
  if (0 != pi->options->rb_enc) {
123
123
  rb_enc_associate(rstr, pi->options->rb_enc);
124
124
  }
125
125
  rb_hash_aset(ah, rstr, rb_str_new2(attrs->value));
126
+ #endif
126
127
  }
127
128
  if (0 == strcmp("encoding", attrs->name)) {
128
129
  pi->options->rb_enc = rb_enc_find(attrs->value);
129
130
  }
130
- #endif
131
131
  }
132
132
  nodes = rb_ary_new();
133
133
  rb_ivar_set(doc, ox_attributes_id, ah);
data/ext/ox/hash_load.c CHANGED
@@ -74,9 +74,8 @@ unmark(PInfo pi, VALUE val) {
74
74
  }
75
75
 
76
76
  static void
77
- add_text(PInfo pi, char *text, int closed) {
77
+ add_str(PInfo pi, VALUE s) {
78
78
  Helper parent = helper_stack_peek(&pi->helpers);
79
- volatile VALUE s = rb_str_new2(text);
80
79
  volatile VALUE a;
81
80
 
82
81
  #if HAVE_RB_ENC_ASSOCIATE
@@ -102,6 +101,16 @@ add_text(PInfo pi, char *text, int closed) {
102
101
  }
103
102
  }
104
103
 
104
+ static void
105
+ add_text(PInfo pi, char *text, int closed) {
106
+ add_str(pi, rb_str_new2(text));
107
+ }
108
+
109
+ static void
110
+ add_cdata(PInfo pi, const char *text, size_t len) {
111
+ add_str(pi, rb_str_new(text, len));
112
+ }
113
+
105
114
  static void
106
115
  add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
107
116
  if (helper_stack_empty(&pi->helpers)) {
@@ -250,6 +259,19 @@ struct _parseCallbacks _ox_hash_callbacks = {
250
259
 
251
260
  ParseCallbacks ox_hash_callbacks = &_ox_hash_callbacks;
252
261
 
262
+ struct _parseCallbacks _ox_hash_cdata_callbacks = {
263
+ NULL,
264
+ NULL,
265
+ NULL,
266
+ add_cdata,
267
+ add_text,
268
+ add_element,
269
+ end_element,
270
+ finish,
271
+ };
272
+
273
+ ParseCallbacks ox_hash_cdata_callbacks = &_ox_hash_cdata_callbacks;
274
+
253
275
  struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
254
276
  NULL,
255
277
  NULL,
@@ -262,3 +284,16 @@ struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
262
284
  };
263
285
 
264
286
  ParseCallbacks ox_hash_no_attrs_callbacks = &_ox_hash_no_attrs_callbacks;
287
+
288
+ struct _parseCallbacks _ox_hash_no_attrs_cdata_callbacks = {
289
+ NULL,
290
+ NULL,
291
+ NULL,
292
+ add_cdata,
293
+ add_text,
294
+ add_element_no_attrs,
295
+ end_element_no_attrs,
296
+ NULL,
297
+ };
298
+
299
+ ParseCallbacks ox_hash_no_attrs_cdata_callbacks = &_ox_hash_no_attrs_cdata_callbacks;
data/ext/ox/obj_load.c CHANGED
@@ -42,10 +42,10 @@ static void fill_indent(PInfo pi, char *buf, size_t size);
42
42
 
43
43
 
44
44
  struct _parseCallbacks _ox_obj_callbacks = {
45
- instruct, /* instruct, */
46
- 0, /* add_doctype, */
47
- 0, /* add_comment, */
48
- 0, /* add_cdata, */
45
+ instruct, // instruct,
46
+ 0, // add_doctype,
47
+ 0, // add_comment,
48
+ 0, // add_cdata,
49
49
  add_text,
50
50
  add_element,
51
51
  end_element,
@@ -128,7 +128,7 @@ resolve_classname(VALUE mod, const char *class_name, Effort effort, VALUE base_c
128
128
  break;
129
129
  case StrictEffort:
130
130
  default:
131
- /* raise an error if name is not defined */
131
+ // raise an error if name is not defined
132
132
  clas = rb_const_get_at(mod, ci);
133
133
  break;
134
134
  }
@@ -183,7 +183,7 @@ parse_ulong(const char *s, PInfo pi) {
183
183
  return ULONG2NUM(n);
184
184
  }
185
185
 
186
- /* 2010-07-09T10:47:45.895826162+09:00 */
186
+ // 2010-07-09T10:47:45.895826162+09:00
187
187
  inline static VALUE
188
188
  parse_time(const char *text, VALUE clas) {
189
189
  VALUE t;
@@ -559,7 +559,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
559
559
  printf("%s%s\n", indent, buf);
560
560
  }
561
561
  }
562
- if (helper_stack_empty(&pi->helpers)) { /* top level object */
562
+ if (helper_stack_empty(&pi->helpers)) { // top level object
563
563
  if (0 != (id = get_id_from_attrs(pi, attrs))) {
564
564
  pi->circ_array = circ_array_new();
565
565
  }
@@ -580,7 +580,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
580
580
  h->obj = Qfalse;
581
581
  break;
582
582
  case StringCode:
583
- /* h->obj will be replaced by add_text if it is called */
583
+ // h->obj will be replaced by add_text if it is called
584
584
  h->obj = ox_empty_string;
585
585
  if (0 != pi->circ_array) {
586
586
  pi->id = get_id_from_attrs(pi, attrs);
@@ -597,8 +597,8 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
597
597
  case ComplexCode:
598
598
  case DateCode:
599
599
  case TimeCode:
600
- case RationalCode: /* sub elements read next */
601
- /* value will be read in the following add_text */
600
+ case RationalCode: // sub elements read next
601
+ // value will be read in the following add_text
602
602
  h->obj = Qundef;
603
603
  break;
604
604
  case String64Code:
@@ -620,7 +620,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
620
620
  }
621
621
  break;
622
622
  case RangeCode:
623
- h->obj = rb_range_new(ox_zero_fixnum, ox_zero_fixnum, Qfalse);
623
+ h->obj = rb_ary_new_from_args(3, Qnil, Qnil, Qfalse);
624
624
  break;
625
625
  case RawCode:
626
626
  if (hasChildren) {
@@ -700,12 +700,15 @@ end_element(PInfo pi, const char *ename) {
700
700
  Helper ph = helper_stack_peek(&pi->helpers);
701
701
 
702
702
  if (ox_empty_string == h->obj) {
703
- /* special catch for empty strings */
703
+ // special catch for empty strings
704
704
  h->obj = rb_str_new2("");
705
- }
706
- if (Qundef == h->obj) {
705
+ } else if (Qundef == h->obj) {
707
706
  set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
708
707
  return;
708
+ } else if (RangeCode == h->type) { // Expect an array of 3 elements.
709
+ const VALUE *ap = RARRAY_PTR(h->obj);
710
+
711
+ h->obj = rb_range_new(*ap, *(ap + 1), Qtrue == *(ap + 2));
709
712
  }
710
713
  pi->obj = h->obj;
711
714
  if (0 != ph) {
@@ -740,11 +743,11 @@ end_element(PInfo pi, const char *ename) {
740
743
  break;
741
744
  case RangeCode:
742
745
  if (ox_beg_id == h->var) {
743
- RSTRUCT_SET(ph->obj, 0, h->obj);
746
+ rb_ary_store(ph->obj, 0, h->obj);
744
747
  } else if (ox_end_id == h->var) {
745
- RSTRUCT_SET(ph->obj, 1, h->obj);
748
+ rb_ary_store(ph->obj, 1, h->obj);
746
749
  } else if (ox_excl_id == h->var) {
747
- RSTRUCT_SET(ph->obj, 2, h->obj);
750
+ rb_ary_store(ph->obj, 2, h->obj);
748
751
  } else {
749
752
  set_error(&pi->err, "Invalid range attribute", pi->str, pi->s);
750
753
  return;
@@ -903,7 +906,7 @@ parse_xsd_time(const char *text, VALUE clas) {
903
906
  #endif
904
907
  }
905
908
 
906
- /* debug functions */
909
+ // debug functions
907
910
  static void
908
911
  fill_indent(PInfo pi, char *buf, size_t size) {
909
912
  size_t cnt;
data/ext/ox/ox.c CHANGED
@@ -145,6 +145,7 @@ static VALUE symbolize_keys_sym;
145
145
  static VALUE symbolize_sym;
146
146
  static VALUE tolerant_sym;
147
147
  static VALUE trace_sym;
148
+ static VALUE with_cdata_sym;
148
149
  static VALUE with_dtd_sym;
149
150
  static VALUE with_instruct_sym;
150
151
  static VALUE with_xml_sym;
@@ -179,6 +180,7 @@ struct _options ox_default_options = {
179
180
  true, // convert_special
180
181
  No, // allow_invalid
181
182
  false, // no_empty
183
+ false, // with_cdata
182
184
  { '\0' }, // inv_repl
183
185
  { '\0' }, // strip_ns
184
186
  NULL, // html_hints
@@ -192,7 +194,9 @@ extern ParseCallbacks ox_gen_callbacks;
192
194
  extern ParseCallbacks ox_limited_callbacks;
193
195
  extern ParseCallbacks ox_nomode_callbacks;
194
196
  extern ParseCallbacks ox_hash_callbacks;
197
+ extern ParseCallbacks ox_hash_cdata_callbacks;
195
198
  extern ParseCallbacks ox_hash_no_attrs_callbacks;
199
+ extern ParseCallbacks ox_hash_no_attrs_cdata_callbacks;
196
200
 
197
201
  static void parse_dump_options(VALUE ropts, Options copts);
198
202
 
@@ -290,6 +294,7 @@ hints_to_overlay(Hints hints) {
290
294
  * - _:convert_special_ [true|false|nil] flag indicating special characters like &lt; are converted with the SAX parser
291
295
  * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
292
296
  * - _:no_empty_ [true|false|nil] flag indicating there should be no empty elements in a dump
297
+ * - _:with_cdata_ [true|false] includes cdata in hash_load results
293
298
  * - _:strip_namespace_ [String|true|false] false or "" results in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
294
299
  * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
295
300
  * - _:active_ - make the normal callback for the element
@@ -324,6 +329,7 @@ get_def_opts(VALUE self) {
324
329
  rb_hash_aset(opts, smart_sym, (Yes == ox_default_options.smart) ? Qtrue : ((No == ox_default_options.smart) ? Qfalse : Qnil));
325
330
  rb_hash_aset(opts, convert_special_sym, (ox_default_options.convert_special) ? Qtrue : Qfalse);
326
331
  rb_hash_aset(opts, no_empty_sym, (ox_default_options.no_empty) ? Qtrue : Qfalse);
332
+ rb_hash_aset(opts, with_cdata_sym, (ox_default_options.with_cdata) ? Qtrue : Qfalse);
327
333
  switch (ox_default_options.mode) {
328
334
  case ObjMode: rb_hash_aset(opts, mode_sym, object_sym); break;
329
335
  case GenMode: rb_hash_aset(opts, mode_sym, generic_sym); break;
@@ -431,6 +437,7 @@ sax_html_overlay(VALUE self) {
431
437
  * - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html)
432
438
  * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
433
439
  * - _:strip_namespace_ [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
440
+ * - _:with_cdata_ [true|false] includes cdata in hash_load results
434
441
  * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
435
442
  * - _:active_ - make the normal callback for the element
436
443
  * - _:nest_ok_ - active but ignore nest check
@@ -630,6 +637,10 @@ set_def_opts(VALUE self, VALUE opts) {
630
637
  rb_hash_foreach(v, set_overlay, (VALUE)ox_default_options.html_hints);
631
638
  }
632
639
  }
640
+ if (Qnil != (v = rb_hash_lookup(opts, with_cdata_sym))) {
641
+ ox_default_options.with_cdata = (Qtrue == v);
642
+ }
643
+
633
644
  ox_default_options.element_key_mod = rb_hash_lookup2(opts, element_key_mod_sym, ox_default_options.element_key_mod);
634
645
  ox_default_options.attr_key_mod = rb_hash_lookup2(opts, attr_key_mod_sym, ox_default_options.attr_key_mod);
635
646
 
@@ -838,6 +849,9 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
838
849
  options.margin[sizeof(options.margin) - 1] = '\0';
839
850
  options.margin_len = strlen(options.margin);
840
851
  }
852
+ if (Qnil != (v = rb_hash_lookup(h, with_cdata_sym))) {
853
+ options.with_cdata = (Qtrue == v);
854
+ }
841
855
  }
842
856
  #if HAVE_RB_ENC_FIND
843
857
  if ('\0' == *options.encoding) {
@@ -869,10 +883,18 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
869
883
  obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err);
870
884
  break;
871
885
  case HashMode:
872
- obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
886
+ if (options.with_cdata) {
887
+ obj = ox_parse(xml, len, ox_hash_cdata_callbacks, 0, &options, err);
888
+ } else {
889
+ obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
890
+ }
873
891
  break;
874
892
  case HashNoAttrMode:
875
- obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
893
+ if (options.with_cdata) {
894
+ obj = ox_parse(xml, len, ox_hash_no_attrs_cdata_callbacks, 0, &options, err);
895
+ } else {
896
+ obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
897
+ }
876
898
  break;
877
899
  case NoMode:
878
900
  obj = ox_parse(xml, len, ox_nomode_callbacks, 0, &options, err);
@@ -908,6 +930,7 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
908
930
  * - *:symbolize_keys* [true|false|nil] symbolize element attribute keys or leave as Strings
909
931
  * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
910
932
  * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
933
+ * - *:with_cdata* [true|false] if true cdata is included in hash_load output otherwise it is not.
911
934
  */
912
935
  static VALUE
913
936
  load_str(int argc, VALUE *argv, VALUE self) {
@@ -1516,6 +1539,7 @@ void Init_ox() {
1516
1539
  symbolize_sym = ID2SYM(rb_intern("symbolize")); rb_gc_register_address(&symbolize_sym);
1517
1540
  tolerant_sym = ID2SYM(rb_intern("tolerant")); rb_gc_register_address(&tolerant_sym);
1518
1541
  trace_sym = ID2SYM(rb_intern("trace")); rb_gc_register_address(&trace_sym);
1542
+ with_cdata_sym = ID2SYM(rb_intern("with_cdata")); rb_gc_register_address(&with_cdata_sym);
1519
1543
  with_dtd_sym = ID2SYM(rb_intern("with_dtd")); rb_gc_register_address(&with_dtd_sym);
1520
1544
  with_instruct_sym = ID2SYM(rb_intern("with_instructions")); rb_gc_register_address(&with_instruct_sym);
1521
1545
  with_xml_sym = ID2SYM(rb_intern("with_xml")); rb_gc_register_address(&with_xml_sym);
data/ext/ox/ox.h CHANGED
@@ -136,6 +136,7 @@ typedef struct _options {
136
136
  char convert_special;// boolean true or false
137
137
  char allow_invalid; // YesNo
138
138
  char no_empty; // boolean - no empty elements when dumping
139
+ char with_cdata; // boolean - hash_load should include cdata
139
140
  char inv_repl[12]; // max 10 valid characters, first character is the length
140
141
  char strip_ns[64]; // namespace to strip, \0 is no-strip, \* is all, else only matches
141
142
  struct _hints *html_hints; // html hints
data/lib/ox/element.rb CHANGED
@@ -115,17 +115,8 @@ module Ox
115
115
  # matching name will be yielded to. If the cond is a Hash then the
116
116
  # keys-value pairs in the cond must match the child attribute values with
117
117
  # the same keys. Any other cond type will yield to nothing.
118
- def each(cond=nil)
119
- if cond.nil?
120
- nodes.each { |n| yield(n) }
121
- else
122
- cond = cond.to_s if cond.is_a?(Symbol)
123
- if cond.is_a?(String)
124
- nodes.each { |n| yield(n) if n.is_a?(Element) && cond == n.name }
125
- elsif cond.is_a?(Hash)
126
- nodes.each { |n| yield(n) if n.is_a?(Element) && n.attr_match(cond) }
127
- end
128
- end
118
+ def each(cond=nil, &block)
119
+ build_enumerator(cond).each(&block)
129
120
  end
130
121
 
131
122
  # Returns an array of Nodes or Strings that correspond to the locations
@@ -413,6 +404,24 @@ module Ox
413
404
 
414
405
  private
415
406
 
407
+ # Builds an enumerator for use in `#each` call
408
+ #
409
+ # - +cond+ [Hash, String, nil] an element filter
410
+ def build_enumerator(cond)
411
+ if cond.nil?
412
+ nodes.each
413
+ else
414
+ cond = cond.to_s if cond.is_a?(Symbol)
415
+ Enumerator.new do |yielder|
416
+ if cond.is_a?(String)
417
+ nodes.each { |n| yielder.yield(n) if n.is_a?(Element) && cond == n.name }
418
+ elsif cond.is_a?(Hash)
419
+ nodes.each { |n| yielder.yield(n) if n.is_a?(Element) && n.attr_match(cond) }
420
+ end
421
+ end
422
+ end
423
+ end
424
+
416
425
  # Removes recursively children for nodes and sub_nodes
417
426
  #
418
427
  # - +found+ [Array] An array of Ox::Element
data/lib/ox/hasattrs.rb CHANGED
@@ -13,7 +13,7 @@ module Ox
13
13
  @attributes = { } if !instance_variable_defined?(:@attributes) or @attributes.nil?
14
14
  @attributes
15
15
  end
16
-
16
+
17
17
  # Returns the value of an attribute.
18
18
  # - +attr+ [Symbol|String] attribute name or key to return the value for
19
19
  def [](attr)
@@ -27,9 +27,16 @@ module Ox
27
27
  def []=(attr, value)
28
28
  raise "argument to [] must be a Symbol or a String." unless attr.is_a?(Symbol) or attr.is_a?(String)
29
29
  @attributes = { } if !instance_variable_defined?(:@attributes) or @attributes.nil?
30
+ a_str = attr.to_s
31
+ a_sym = attr.to_sym
32
+ if @attributes.has_key?(a_str)
33
+ attr = a_str
34
+ elsif @attributes.has_key?(a_sym)
35
+ attr = a_sym
36
+ end
30
37
  @attributes[attr] = value.to_s
31
38
  end
32
-
39
+
33
40
  # Handles the 'easy' API that allows navigating a simple XML by
34
41
  # referencing attributes by name.
35
42
  # - +id+ [Symbol] element or attribute name
data/lib/ox/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Ox
3
3
  # Current version of the module.
4
- VERSION = '2.13.4'
4
+ VERSION = '2.14.4'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.4
4
+ version: 2.14.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-11 00:00:00.000000000 Z
11
+ date: 2021-03-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: "A fast XML parser and object serializer that uses only standard C lib.\n\nOptimized
14
14
  XML (Ox), as the name implies was written to provide speed optimized\nXML handling.
@@ -76,7 +76,7 @@ homepage: http://www.ohler.com/ox
76
76
  licenses:
77
77
  - MIT
78
78
  metadata: {}
79
- post_install_message:
79
+ post_install_message:
80
80
  rdoc_options:
81
81
  - "--main"
82
82
  - README.md
@@ -98,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  - !ruby/object:Gem::Version
99
99
  version: '0'
100
100
  requirements: []
101
- rubygems_version: 3.1.2
102
- signing_key:
101
+ rubygems_version: 3.2.3
102
+ signing_key:
103
103
  specification_version: 4
104
104
  summary: A fast XML parser and object serializer.
105
105
  test_files: []