ixyml 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. data/.gitignore +19 -0
  2. data/.gitignore~ +17 -0
  3. data/Gemfile +12 -0
  4. data/Gemfile.lock +44 -0
  5. data/Gemfile~ +13 -0
  6. data/LICENSE +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +2 -0
  9. data/bin/dbg_x2o +8 -0
  10. data/bin/x2y +8 -0
  11. data/bin/y2x +17 -0
  12. data/ixyml.gemspec +23 -0
  13. data/lib/ixyml.rb +10 -0
  14. data/lib/ixyml/version.rb +3 -0
  15. data/lib/ixyml/xyml.rb +821 -0
  16. data/lib/ixyml/xyml_element.rb +778 -0
  17. data/test/dirTemp/ktest00.nml.j2j.json +1 -0
  18. data/test/dirTemp/ktest00.nml.nml.xml +53 -0
  19. data/test/dirTemp/ktest00.nml.nml.yaml +74 -0
  20. data/test/dirTemp/ktest00.nml.x2j.json +1 -0
  21. data/test/dirTemp/ktest00.nml.x2x.xml +53 -0
  22. data/test/dirTemp/ktest00.nml.xyj.yaml +134 -0
  23. data/test/dirTemp/ktest00.nml.xyx.xml +53 -0
  24. data/test/dirTemp/ktest00.nml.xyx.yaml +134 -0
  25. data/test/dirTemp/ktest00.nml.y2j.json +1 -0
  26. data/test/dirTemp/ktest00.nml.y2y.yaml +74 -0
  27. data/test/dirTemp/ktest00.nml.yxy.xml +2 -0
  28. data/test/dirTemp/ktest00.nml.yxy.yaml +74 -0
  29. data/test/dirTemp/ktest01.nml.yaml +74 -0
  30. data/test/dirTemp/ktest01.yxy.xml +2 -0
  31. data/test/dirTemp/ktest01.yxy.yaml +74 -0
  32. data/test/dirTemp/test01.nml.nml.xml +21 -0
  33. data/test/dirTemp/test01.nml.nml.yaml +5 -0
  34. data/test/dirTemp/test01.nml.x2j.json +1 -0
  35. data/test/dirTemp/test01.nml.x2x.xml +21 -0
  36. data/test/dirTemp/test01.nml.xyj.yaml +18 -0
  37. data/test/dirTemp/test01.nml.xyx.xml +21 -0
  38. data/test/dirTemp/test01.nml.xyx.yaml +18 -0
  39. data/test/dirTemp/test01.nml.y2j.json +1 -0
  40. data/test/dirTemp/test01.nml.y2y.yaml +5 -0
  41. data/test/dirTemp/test01.nml.yaml +74 -0
  42. data/test/dirTemp/test01.nml.yxy.xml +3 -0
  43. data/test/dirTemp/test01.nml.yxy.yaml +5 -0
  44. data/test/dirTemp/test01.yxy.xml +2 -0
  45. data/test/dirTemp/test01.yxy.yaml +74 -0
  46. data/test/dirTemp/testBreak.nml.yaml +7 -0
  47. data/test/dirTemp/testBreak.yxy.xml +5 -0
  48. data/test/dirTemp/testBreak.yxy.yaml +7 -0
  49. data/test/dirTemp/testCDATA.nml.nml.xml +26 -0
  50. data/test/dirTemp/testCDATA.nml.x2j.json +1 -0
  51. data/test/dirTemp/testCDATA.nml.x2x.xml +26 -0
  52. data/test/dirTemp/testCDATA.nml.xyj.yaml +18 -0
  53. data/test/dirTemp/testCDATA.nml.xyx.xml +26 -0
  54. data/test/dirTemp/testCDATA.nml.xyx.yaml +18 -0
  55. data/test/dirTemp/testCDATA.nml.y2j.json +1 -0
  56. data/test/dirTemp/testEscape.nml.nml.xml +77 -0
  57. data/test/dirTemp/testEscape.nml.nml.yaml +53 -0
  58. data/test/dirTemp/testEscape.nml.x2j.json +1 -0
  59. data/test/dirTemp/testEscape.nml.x2x.xml +77 -0
  60. data/test/dirTemp/testEscape.nml.xyj.yaml +213 -0
  61. data/test/dirTemp/testEscape.nml.xyx.xml +77 -0
  62. data/test/dirTemp/testEscape.nml.xyx.yaml +213 -0
  63. data/test/dirTemp/testEscape.nml.y2j.json +1 -0
  64. data/test/dirTemp/testEscape.nml.y2y.yaml +53 -0
  65. data/test/dirTemp/testEscape.nml.yxy.xml +2 -0
  66. data/test/dirTemp/testEscape.nml.yxy.yaml +53 -0
  67. data/test/dirTemp/testNS.nml.nml.xml +21 -0
  68. data/test/dirTemp/testNS.nml.x2j.json +1 -0
  69. data/test/dirTemp/testNS.nml.x2x.xml +21 -0
  70. data/test/dirTemp/testNS.nml.xyj.yaml +19 -0
  71. data/test/dirTemp/testNS.nml.xyx.xml +21 -0
  72. data/test/dirTemp/testNS.nml.xyx.yaml +19 -0
  73. data/test/dirTemp/testNS.nml.y2j.json +1 -0
  74. data/test/test_xyml.rb +167 -0
  75. data/test/test_xyml.rb~ +167 -0
  76. data/test/test_xyml_element.rb +241 -0
  77. data/test/test_xyml_element.rb~ +111 -0
  78. data/test/testfiles/ktest00.nml.ori.json +1 -0
  79. data/test/testfiles/ktest00.nml.ori.xml +53 -0
  80. data/test/testfiles/ktest00.nml.ori.yaml +74 -0
  81. data/test/testfiles/ktest00.nml.ori.yaml~ +75 -0
  82. data/test/testfiles/ktest01.ori.yaml +75 -0
  83. data/test/testfiles/test01.nml.ori.xml +21 -0
  84. data/test/testfiles/test01.nml.ori.yaml +5 -0
  85. data/test/testfiles/test01.ori.yaml +75 -0
  86. data/test/testfiles/testBreak.ori.yaml +10 -0
  87. data/test/testfiles/testCDATA.ng.ng.xml +26 -0
  88. data/test/testfiles/testEscape.nml.ori.xml +77 -0
  89. data/test/testfiles/testEscape.nml.ori.yaml +105 -0
  90. data/test/testfiles/testNS.nml.ori.xml +21 -0
  91. data/test/testfiles/xmlTemp.xml +2 -0
  92. data/test/testfiles/xymlTemp.xyml +6 -0
  93. metadata +230 -0
@@ -0,0 +1,778 @@
1
+ #
2
+ # Xyml_element module is for handling a XYML tree data loaded from a XYML format file.
3
+ # (See Xyml module for detailed information of XYML.)
4
+ #
5
+ # Xyml_elementモジュールは、XYML形式のファイルをロードして得たXYMLツリー構造データを
6
+ # 操作するためのモジュールである。XYML形式については、Xymlモジュールのドキュメントを参照してください。
7
+ #
8
+ #
9
+ # == (1) data model
10
+ #
11
+ # In the APIs provided by this module, only "elements" in XYML tree data are treated as objects.
12
+ # Their attribures, related elements such as child elements and texts can be accessed via
13
+ # APIs of the elements.
14
+ #
15
+ # == (1)データモデル
16
+ #
17
+ # 本モジュールが提供するAPIでは、XYMLツリー構造データのエレメントのみオブジェクトとして扱われる。
18
+ # その属性や子エレメントなどの関連エレメント、テキストへのアクセス手段が、エレメントのAPIとして提供される。
19
+ #
20
+ # +-- element --------------------+
21
+ # | |
22
+ # access to attributes | +-- attributes ----+ |
23
+ # ------------------------+---->| | |
24
+ # | +------------------+ |
25
+ # | |
26
+ # access to child nodes | +-- child nodes ---+ |
27
+ # ------------------------+---->| | |
28
+ # | +------------------+ |
29
+ # | |
30
+ # access to text | +-- text -------------+ |
31
+ # ------------------------+---->| | |
32
+ # | +---------------------+ |
33
+ # | |
34
+ # access to parent element| +-- parent element(*)-+ |
35
+ # ------------------------+---->| | |
36
+ # | +---------------------+ |
37
+ # +-------------------------------+
38
+ # (*) data designating the parent element is attached when XYML tree data is constructed(e.g. when file loaded).
39
+ #
40
+ # == (2) Xyml::Element class
41
+ #
42
+ # In XYML tree data, an element corresponds to a hash which has only one pair of key and value,
43
+ # where the key stands for the element name and the value is an array of attributes,
44
+ # child elements and texts. Note the key must be a symbol.
45
+ #
46
+ # Xyml::Element class inherits Hash, includes this Xyml_element module, and has an array at the first place in its hash values.
47
+ # All methods except '.new' of Xyml::Element class are in this Xyml_element module.
48
+ #
49
+ # == (2) Xyml::Elementクラス
50
+ #
51
+ # XYMLツリー構造データでは、エレメントは、キー・バリュー対が一つだけのハッシュに対応する。
52
+ # そのキーが要素名を表し、そのバリューは属性と子エレメントとテキストが要素である配列となる。
53
+ #
54
+ # Xyml::Elementクラスは、ハッシュを継承し、このXyml_elementモジュールをインクルードし、ハッシュのバリューの先頭に配列を持つ。
55
+ # 'new'以外のXyml::Elementクラスのメソッドは、すべて本Xyml_elementモジュール内にある。
56
+ #
57
+ # # | XML | XYML | Xyml::Element class |
58
+ # # | <a b='CCC'> | -a: | {a: [{b:'CCC'},{d:[{e:'FFF'},'text']}]} |
59
+ # # | <d e="FFF"> | -b: CCC | ---------------------- |
60
+ # # | text | -d: | Xyml::Element class |
61
+ # # | </d> | -e: FFF | --------------------------------------- |
62
+ # # | </a> | - text | Xyml::Element class |
63
+ #
64
+ # == (3) loaded XYML data
65
+ #
66
+ # If you load XYML tree data from a XYML file by using the methods in Xyml module,
67
+ # the extensions to this Xyml_element module have already been done.
68
+ #
69
+ # == (3) ロードされたXYMLデータ
70
+ #
71
+ # Xymlモジュール内のメソッドを使ってXYMLツリー構造データをファイルからロードした場合には、
72
+ # このXyml_elemetモジュールへの拡張がすでに行われている。
73
+ #
74
+ # == (4) method names
75
+ #
76
+ # The name of each method in this module is a seris of three short strings which stand for
77
+ # 'operation','object' and 'condition' respectively.
78
+ #
79
+ # == (4) メソッド名
80
+ #
81
+ # 本モジュールのメソッド名は、操作(operation)/対象(object)/条件(condition)を表す文字列を
82
+ # 順に並べたものになっている。
83
+ #
84
+ # .gcfn -> g(oepration) cf(object) n(condition)
85
+ #
86
+ # +-- operation --+ +-- object ---------------+ +-- condition(what designated?) --+
87
+ # | g : get | | c : children | | n : element name |
88
+ # | a : add | | cf: first child | | a : attribute name and value |
89
+ # | i : insert | | sl: self | | na: element and attribute |
90
+ # | d : delete | | sp: previous sibling | +---------------------------------+
91
+ # | s : set | | ss: immediately |
92
+ # +---------------+ | succeeding sibling |
93
+ # | p : parent |
94
+ # | r : root |
95
+ # | a : attribute |
96
+ # | t : text |
97
+ # +-------------------------+
98
+ #
99
+ # == (5) about usage examples
100
+ #
101
+ # In the usage example for each method, it is assumed that the lines of program code shown below have
102
+ # already done(see Xyml module).
103
+ #
104
+ # == (5) 使用例について
105
+ #
106
+ # メソッドの使用例については、次のプログラムに続けて行われているものとする(Xymlモジュール参照)。
107
+ #
108
+ # # aaa.xyml
109
+ # # - a:
110
+ # # - b: ccc
111
+ # # - d:
112
+ # # - e: fff
113
+ # # - d:
114
+ # # - e: ggg
115
+ # # - text
116
+ # # - h:
117
+ # # - e: fff
118
+ # xyml_tree=Xyml::Document.new(File.open("aaa.xyml"))
119
+ # #-> [{a:[{b:'ccc'},{d:[{e:'fff'}]},{d:[{e:'ggg'},'text']},{h:[{e:'fff'}]}]}]
120
+ #
121
+ module Xyml_element
122
+
123
+ # return element's name
124
+ #
125
+ # エレメントの名前を返す。
126
+ def name
127
+ self.keys[0]
128
+ end
129
+
130
+
131
+ # get child elements.
132
+ #
133
+ # 子エレメントの取得
134
+ # ==== Return
135
+ # an array of elements.
136
+ #
137
+ # エレメントの配列
138
+ #
139
+ # xyml_tree.root.gc
140
+ # #-> [{d:[{e:"fff"}]},{d:[{e:"ggg"}]},{h:[{e:'fff'}]}]
141
+ def gc
142
+ array=Array.new
143
+ self.values[0].each do |child|
144
+ array << child if child.is_a?(Hash) && child.values[0].is_a?(Array)
145
+ end
146
+ array
147
+ end
148
+
149
+ # get the first child element.
150
+ #
151
+ # 最初の子エレメントの取得
152
+ # ==== Return
153
+ # an element, or nil if no children
154
+ #
155
+ # エレメント(子エレメントが無い場合は'nil')
156
+ #
157
+ # xyml_tree.root.gcf
158
+ # #-> {d:[{e:'fff'}]}
159
+ def gcf
160
+ self.values[0].each do |child|
161
+ return child if child.is_a?(Hash) && child.values[0].is_a?(Array)
162
+ end
163
+ nil
164
+ end
165
+
166
+ # get child elements with the designated name.
167
+ #
168
+ # 指定された名前を持つ子エレメントの取得
169
+ # ==== Args
170
+ # _ename_ :: element name(string or symbol).
171
+ #
172
+ # _ename_ :: エレメント名(文字列もしくはシンボル)
173
+ # ==== Return
174
+ # an array of elements.
175
+ #
176
+ # エレメントの配列
177
+ #
178
+ # xyml_tree.root.gcn 'd' # or xyml_tree.root.gcn :d
179
+ # #-> [{d:[{e:"fff"}]},{d:[{e:"ggg"},'text']}]
180
+ def gcn ename
181
+ ename=ename.intern if ename.is_a?(String)
182
+ array=Array.new
183
+ self.values[0].each do |child|
184
+ array << child if child.is_a?(Hash) && child.keys[0]==ename && child.values[0].is_a?(Array)
185
+ end
186
+ array
187
+ end
188
+
189
+ # get the first child element with the designated name.
190
+ #
191
+ # 指定された名前を持つ最初の子エレメントの取得
192
+ # ==== Return
193
+ # an element, or nil if no children with the designated name.
194
+ #
195
+ # エレメント(指定された名前の子エレメントが無い場合は'nil')
196
+ #
197
+ # xyml_tree.root.gcfn 'd' # or xyml_tree.root.gcfn :d
198
+ # #-> {d:[{e:"fff"}]}
199
+ def gcfn ename
200
+ ename=ename.intern if ename.is_a?(String)
201
+ self.values[0].each do |child|
202
+ return child if child.is_a?(Hash) && child.keys[0]==ename && child.values[0].is_a?(Array)
203
+ end
204
+ nil
205
+ end
206
+
207
+ # get child elements with the designated element name and atrribute.
208
+ #
209
+ # 指定された名前と属性を持つ子エレメントの取得
210
+ # ==== Args
211
+ # _ename_ :: element name(string or symbol)
212
+ # _aname_ :: attribute name(string or symbol)
213
+ # _avalue_ :: attribute value
214
+ #
215
+ # _ename_ :: エレメント名(文字列もしくはシンボル)
216
+ # _aname_ :: 属性名(文字列もしくはシンボル)
217
+ # _avalue_ :: 属性値
218
+ # ==== Return
219
+ # an array of elements.
220
+ #
221
+ # エレメントの配列
222
+ #
223
+ # xyml_tree.root.gcna 'd','e','ggg'
224
+ # #-> [{d:[{e:"ggg"},'text']}]
225
+ def gcna ename,aname,avalue
226
+ ename=ename.intern if ename.is_a?(String)
227
+ aname=aname.intern if aname.is_a?(String)
228
+ array=Array.new
229
+ self.values[0].each do |child|
230
+ array << child if child.is_a?(Hash) && child.keys[0]==ename && child.values[0].is_a?(Array) && child.ga(aname)==avalue
231
+ end
232
+ array
233
+ end
234
+
235
+ # get child elements with the designated atrribute.
236
+ #
237
+ # 指定された属性を持つ子エレメントの取得
238
+ # ==== Args
239
+ # _aname_ :: attribute name(string or symbol)
240
+ # _avalue_ :: attribute value
241
+ #
242
+ # _aname_ :: 属性名(文字列もしくはシンボル)
243
+ # _avalue_ :: 属性値
244
+ # ==== Return
245
+ # an array of elements.
246
+ #
247
+ # エレメントの配列
248
+ #
249
+ # xyml_tree.root.gca 'e','fff'
250
+ # #-> [{d:[{e:"fff"}]},{h:[{e:"fff"}]}]
251
+ def gca aname,avalue
252
+ aname=aname.intern if aname.is_a?(String)
253
+ array=Array.new
254
+ self.values[0].each do |child|
255
+ array << child if child.is_a?(Hash) && child.values[0].is_a?(Array) && child.ga(aname)==avalue
256
+ end
257
+ array
258
+ end
259
+
260
+
261
+ # get the first child elements with the designated element name and atrribute.
262
+ #
263
+ # 指定された名前と属性を持つ最初の子エレメントの取得
264
+ # ==== Args
265
+ # _ename_ :: element name(string or symbol)
266
+ # _aname_ :: attribute name(string or symbol)
267
+ # _avalue_ :: attribute value
268
+ #
269
+ # _ename_ :: エレメント名(文字列もしくはシンボル)
270
+ # _aname_ :: 属性名(文字列もしくはシンボル)
271
+ # _avalue_ :: 属性値
272
+ # ==== Return
273
+ # an element, or nil if no children with the designated name and attribute.
274
+ #
275
+ # エレメント(指定された名前と属性の子エレメントが無い場合は'nil')
276
+ #
277
+ # xyml_tree.root.gcfna 'd','e','ggg'
278
+ # #-> {d:[{e:"ggg"},'text']}
279
+ def gcfna ename,aname,avalue
280
+ ename=ename.intern if ename.is_a?(String)
281
+ aname=aname.intern if aname.is_a?(String)
282
+ self.values[0].each do |child|
283
+ return child if child.is_a?(Hash) && child.keys[0]==ename && child.values[0].is_a?(Array) && child.ga(aname)==avalue
284
+ end
285
+ nil
286
+ end
287
+
288
+ # get the previous sibling element.
289
+ #
290
+ # 直前のシブリング(兄弟姉妹)エレメントの取得。
291
+ # ==== Return
292
+ # an element, or nil if no previous sibling element.
293
+ #
294
+ # エレメント(自身が最初の子エレメントの場合は'nil')
295
+ #
296
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
297
+ # #-> {d:[{e:"ggg"},'text']}
298
+ # my_element.gsp
299
+ # #-> {d:[{e:"fff"}]}
300
+ def gsp
301
+ if parent=self.gp then
302
+ siblings=parent.gc
303
+ #print "#D#xyml_element.rb:gsp:sliblings=";pp siblings
304
+ siblings.each_with_index do |sibling,index|
305
+ if sibling==self then
306
+ if index==0 then
307
+ return nil
308
+ else
309
+ return siblings[index-1]
310
+ end
311
+ end
312
+ end
313
+ end
314
+ end
315
+
316
+ # get the immediately succeeding sibling element.
317
+ #
318
+ # 直後のシブリング(兄弟姉妹)エレメントの取得。
319
+ # ==== Return
320
+ # an element, or nil if no next sibling element.
321
+ #
322
+ # エレメント(自身が最後の子エレメントの場合は'nil')
323
+ #
324
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
325
+ # #-> {d:[{e:"ggg"},'text']}
326
+ # my_element.gss
327
+ # #-> {h:[{e:"fff"}]}
328
+ def gss
329
+ if parent=self.gp then
330
+ siblings=parent.gc
331
+ #print "#D#xyml_element.rb:gsp:sliblings=";pp siblings
332
+ siblings.each_with_index do |sibling,index|
333
+ if sibling==self then
334
+ if index==siblings.length-1 then
335
+ return nil
336
+ else
337
+ return siblings[index+1]
338
+ end
339
+ end
340
+ end
341
+ end
342
+ end
343
+
344
+ # add a child element.
345
+ #
346
+ # 子エレメントの追加。
347
+ # ==== Args
348
+ # _elm_ :: an element to add(or a hash that can extend Xyml_element module).
349
+ #
350
+ # _elm_ :: 追加するエレメント(もしくは、Xyml_elementモジュールを拡張しうるハッシュ)
351
+ # ==== Return
352
+ # the element added(or nil if Xyml_element module can be extended).
353
+ #
354
+ # 追加されたエレメント(Xyml_elementモジュールを拡張出来ない場合は'nil')
355
+ # ==== Note
356
+ # This method make the input object extend Xyml_element module.
357
+ #
358
+ # このメソッドは、入力に対して、Xyml_elemenntモジュールの拡張を実施させる
359
+ #
360
+ #
361
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
362
+ # #-> {d:[{e:"ggg"},'text']}
363
+ # my_element.ac {j:[{e:'kkk'}]}
364
+ # my_element.gcf
365
+ # #-> {j:[{e:"kkk"}]}
366
+ # xyml_tree
367
+ # #-> [{a:[{b:'ccc'},{d:[{e:'fff'}]},{d:[{e:'ggg'},'text',{j:[e:"kkk"]}]},{h:[{e:'fff'}]}]}] #<- element was added next to text.
368
+ # my_element.st(my_elment.gt) #<- text was unset and set again.
369
+ # xyml_tree
370
+ # #-> [{a:[{b:'ccc'},{d:[{e:'fff'}]},{d:[{e:'ggg'},{j:[e:"kkk"]},'text']},{h:[{e:'fff'}]}]}] #<- text next to added element.
371
+ def ac elm
372
+ return nil unless elm.is_a?(Hash) and elm.values[0].is_a?(Array)
373
+ elm.extend Xyml_element
374
+ self.values[0].push(elm)
375
+ elm._sp(self)
376
+ elm
377
+ end
378
+
379
+ # insert an element as a previous sibling element.
380
+ #
381
+ # 直前のシブリング(兄弟姉妹)エレメントとして、エレメントを挿入
382
+ # ==== Args
383
+ # _elm_ :: an element to insert(or a hash that can extend Xyml_element module).
384
+ #
385
+ # _elm_ :: 挿入するエレメント(もしくは、Xyml_elementモジュールを拡張しうるハッシュ)
386
+ # ==== Return
387
+ # the inserted element.
388
+ #
389
+ # 挿入されたエレメント
390
+ # ==== Note
391
+ # This method make the input extend Xyml_element module.
392
+ #
393
+ # このメソッドは、入力に対して、Xyml_elemenntモジュールの拡張を実施させる
394
+ #
395
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
396
+ # #-> {d:[{e:"ggg"},'text']}
397
+ # my_element.isp {j:[{e:'kkk'}]}
398
+ # my_element.gsp
399
+ # #-> {j:[{e:"kkk"}]}
400
+ # xyml_tree
401
+ # #-> [{a:[{b:'ccc'},{d:[{e:'fff'}]},{j:[{e:"kkk"}]},{d:[{e:'ggg'},'text']},{h:[{e:'fff'}]}]}]
402
+ def isp elm
403
+ return nil if self.gp==:_iamroot
404
+ elm.extend Xyml_element
405
+ parent=self.gp
406
+ parent.values[0].each_with_index do |sibling,index|
407
+ if sibling==self then
408
+ parent.values[0].insert(index,elm)
409
+ elm._sp(parent)
410
+ break
411
+ end
412
+ end
413
+ elm
414
+ end
415
+
416
+ # insert an element as an immediately succeeding sibling element.
417
+ #
418
+ # 直後のシブリング(兄弟姉妹)エレメントとして、エレメントを挿入
419
+ # ==== Args
420
+ # _elm_ :: an element to insert(or a hash that can extend Xyml_element module).
421
+ #
422
+ # _elm_ :: 挿入するエレメント(もしくは、Xyml_elementモジュールを拡張しうるハッシュ)
423
+ # ==== Return
424
+ # the inserted element.
425
+ #
426
+ # 挿入されたエレメント
427
+ # ==== Note
428
+ # This method make the input extend Xyml_element module.
429
+ #
430
+ # このメソッドは、入力に対して、Xyml_elemenntモジュールの拡張を実施させる
431
+ #
432
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
433
+ # #-> {d:[{e:"ggg"},'text']}
434
+ # my_element.iss {j:[{e:'kkk'}]}
435
+ # my_element.gss
436
+ # #-> {j:[{e:"kkk"}]}
437
+ # xyml_tree
438
+ # #-> [{a:[{b:'ccc'},{d:[{e:'fff'}]},{d:[{e:'ggg'},'text']},{j:[{e:"kkk"}]},{h:[{e:'fff'}]}]}]
439
+ def iss elm
440
+ return nil if self.gp==:_iamroot
441
+ elm.extend Xyml_element
442
+ parent=self.gp
443
+ parent.values[0].each_with_index do |sibling,index|
444
+ if sibling==self then
445
+ parent.values[0].insert(index+1,elm)
446
+ elm._sp(parent)
447
+ break
448
+ end
449
+ end
450
+ elm
451
+ end
452
+
453
+ # get value of attribute with the designated attribute name.
454
+ #
455
+ # 指定された属性名に対する属性値の取得
456
+ # ==== Args
457
+ # _aname_ :: attribute name(string or symbol)
458
+ #
459
+ # _aname_ :: 属性名(文字列もしくはシンボル)
460
+ #
461
+ # xyml_tree.root.ga(:b)
462
+ # #-> 'ccc'
463
+ # ==== Return
464
+ # attribute value, or nil if no attribute with the designated name.
465
+ #
466
+ # 属性値(指定された属性名の属性が無い場合は、nil)
467
+ def ga aname
468
+ aname=aname.intern if aname.is_a?(String)
469
+ self.values[0].each do |child|
470
+ return child.values[0] if child.is_a?(Hash) && child.keys[0]==aname && (!child.values[0].is_a?(Hash) || !child.values[0].is_a?(Array))
471
+ end
472
+ nil
473
+ end
474
+
475
+ # set value to the attribute with the designated attribute name.
476
+ #
477
+ # 指定された属性名に対する属性値の設定
478
+ # ==== Args
479
+ # _aname_ :: attribute name(string or symbol)
480
+ # _avalue_ :: attribute value
481
+ #
482
+ # _aname_ :: 属性名(文字列もしくはシンボル)
483
+ # _avalue_ :: 属性値
484
+ # ==== Return
485
+ # element itself.
486
+ #
487
+ # エレメント自身
488
+ #
489
+ # xyml_tree.root.sa(:b,'lll')
490
+ # xyml_tree.root.ga(:b)
491
+ # #-> 'lll'
492
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
493
+ # #-> {d:[{e:"ggg"},'text']}
494
+ # my_element.sa(:e,'lll').sa(:m,'nnn')
495
+ # #-> {d:[{e:"lll"},{m:"nnn"},'text']}
496
+ def sa aname,avalue
497
+ aname=aname.intern if aname.is_a?(String)
498
+ return nil if avalue.is_a?(Array) || avalue.is_a?(Hash)
499
+ self.values[0].each_with_index do |child,index|
500
+ if child.is_a?(Hash)
501
+ #p "#D#syml_element.rb:sa:aname=#{aname},avalue=#{avalue},child=#{child}"
502
+ if child.values[0].is_a?(Array) then
503
+ self.values[0].insert(index,Hash[aname,avalue])
504
+ return self
505
+ end
506
+ if child.keys[0]==aname && !child.values[0].is_a?(Array) then
507
+ child[aname]=avalue
508
+ return self
509
+ end
510
+ elsif child.is_a?(String) then
511
+ self.values[0].insert(index,Hash[aname,avalue])
512
+ return self
513
+ end
514
+ end
515
+ values[0].push Hash[aname,avalue]
516
+ self
517
+ end
518
+
519
+ # delete attribute.
520
+ #
521
+ # 指定された属性名に対する属性の削除
522
+ # ==== Args
523
+ # _aname_ :: attribute name(string or symbol)
524
+ #
525
+ # _aname_ :: 属性名(文字列もしくはシンボル)
526
+ # ==== Return
527
+ # element itself, or nil if no attribute with the designated name.
528
+ #
529
+ # エレメント自身(指定された属性名の属性が無い場合は、nil)
530
+ #
531
+ # xyml_tree.root.da(:b)
532
+ # xyml_tree.root.ga(:b)
533
+ # #-> nil
534
+ def da aname
535
+ aname=aname.intern if aname.is_a?(String)
536
+ self.values[0].each_with_index do |child,index|
537
+ if child.is_a?(Hash)
538
+ #p "#D#syml_element.rb:sa:aname=#{aname},avalue=#{avalue},child=#{child}"
539
+ if child.values[0].is_a?(Array) then
540
+ return nil
541
+ end
542
+ if child.keys[0]==aname && !child.values[0].is_a?(Array) then
543
+ self.values[0].delete_at(index)
544
+ return self
545
+ end
546
+ elsif child.is_a?(String) then
547
+ return nil
548
+ end
549
+ end
550
+ nil
551
+ end
552
+
553
+ # get text.
554
+ #
555
+ # テキストの取得
556
+ # ==== Args
557
+ # _param_ :: return joined text if omitted. Return the array of parted text if ":raw" is designated.
558
+ #
559
+ # _param_ :: 省略時は、結合されたテキストを返す。":raw"が指定された場合は、分かち書きされたテキストの配列を返す。
560
+ #
561
+ # ==== Return
562
+ # String (or Array of Strings if :raw is designated as _param_)
563
+ #
564
+ # 文字列 (もしくは、:rawが指定された場合は、文字列の配列)
565
+ #
566
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
567
+ # #-> {d:[{e:"ggg"},'text']}
568
+ # my_element.gt
569
+ # #-> 'text'
570
+ # my_element.at 'abc'
571
+ # my_element.gt
572
+ # #-> 'textabc'
573
+ # my_element.gt :raw
574
+ # #-> ['text','abc']
575
+ def gt(param=false)
576
+ array=Array.new
577
+ self.values[0].each do |child|
578
+ unless child.is_a?(Hash) || child.is_a?(Array)
579
+ array.push child
580
+ end
581
+ end
582
+ if param then
583
+ if param==:raw then
584
+ return array
585
+ end
586
+ end
587
+ array.join
588
+ end
589
+
590
+ # set text.
591
+ #
592
+ # テキストの設定
593
+ # ==== Args
594
+ # _text_ :: text(or object with the method 'to_s'), or nil if deleting text.
595
+ #
596
+ # _text_ :: テキスト(もしくは、'to_s'メソッドを持つオブジェクト)、もしくはnil(テキストを消したい場合)
597
+ # ==== Return
598
+ # element itself.
599
+ #
600
+ # エレメント自身。
601
+ #
602
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
603
+ # #-> {d:[{e:"ggg"},'text']}
604
+ # my_element.st 'abc'
605
+ # my_element.gt
606
+ # #-> 'abc'
607
+ # my_elemet.st nil
608
+ # my_element.gt
609
+ # #-> ''
610
+ def st value
611
+ #p "#D#xyml_element.rb:st:(1)caller=#{caller[0]}"
612
+ value=value.to_s
613
+ tempArray=Array.new
614
+ self.values[0].each do |child|
615
+ unless child.is_a?(String)
616
+ tempArray.push child
617
+ end
618
+ end
619
+ self[keys[0]]=tempArray
620
+ self.values[0].push value if value
621
+ self
622
+ end
623
+
624
+ # add text.
625
+ #
626
+ # テキストの追加
627
+ # ==== Args
628
+ # _text_ :: text(or object with the method 'to_s')
629
+ #
630
+ # _text_ :: テキスト(もしくは、'to_s'メソッドを持つオブジェクト)
631
+ # ==== Return
632
+ # element itself.
633
+ #
634
+ # エレメント自身。
635
+ # ==== Note
636
+ # the added text is stored in the last position on the element's array. see 'gt.'
637
+ #
638
+ # 追加されたテキストは、エレメントの配列に末尾に格納される。gtメソッド参照。
639
+ #
640
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
641
+ # #-> {d:[{e:"ggg"},'text']}
642
+ # my_element.at 'abc'
643
+ # my_element.gt
644
+ # #-> 'textabc'
645
+ def at value
646
+ value=value.to_s
647
+ self.values[0].push value
648
+ self
649
+ end
650
+
651
+ # set a parent element information.
652
+ #
653
+ # 親エレメント情報の設定
654
+ # ==== Args.
655
+ # _parent_ :: parent element
656
+ #
657
+ # _parent_ :: 親エレメント
658
+ # ==== Note
659
+ # This method is for the Xyml and Xyml_element module development use, not for users. Use 'ac(add child)' instead.
660
+ #
661
+ # このメソッドは、Xyml、および、Xyml_elementモジュールの開発向けのものであり、ユーザ向けではない。
662
+ # ユーザは"ac(add child)"を使用してください。
663
+ def _sp parent
664
+ self._dp
665
+ if self.keys[0]==:_parent then
666
+ self[:__parent]=parent
667
+ else
668
+ self[:_parent]=parent
669
+ end
670
+ self
671
+ end
672
+
673
+ # delete the parent element information.
674
+ #
675
+ # 親エレメントj情報の削除
676
+ # ==== Note
677
+ # this method is for the Xyml and Xyml_element package development use, not for users.
678
+ #
679
+ # このメソッドは、Xyml、および、Xyml_elementモジュールの開発向けのものであり、ユーザ向けではない。
680
+ def _dp
681
+ (self.keys.size-1).times{|i| self.delete(self.keys[i+1])}
682
+ end
683
+
684
+ # get the parent element.
685
+ #
686
+ # 親エレメントの取得。
687
+ # ==== Return
688
+ # the parent element, or nil if no parent element.
689
+ #
690
+ # エレメント(もしくは、親エレメントが無い場合、"nil")
691
+ #
692
+ # my_element=xyml_tree.root.gcfna 'd','e','ggg'
693
+ # my_element.gp
694
+ # #-> {a:[...]}
695
+ def gp
696
+ parent=self.values[1]
697
+ if parent==:_iamroot then
698
+ nil
699
+ else
700
+ parent
701
+ end
702
+ end
703
+
704
+ # get the root element.
705
+ #
706
+ # ルートエレメントの取得
707
+ # ==== Return
708
+ # the root element, or nil if no root element.
709
+ #
710
+ # ルートエレメント(もしくは、ルートエレメントが無い場合、"nil")
711
+ # new_element=Xyml::Element.new(:j)
712
+ # xyml_tree.root.gcfna('d','e','ggg').ac new_element
713
+ # new_element.gr
714
+ # #-> {a:[...]}
715
+ def gr
716
+ elm=self
717
+ while true do
718
+ if elm.values[1]==:_iamroot then
719
+ return elm
720
+ elsif elm.values[1]==nil then
721
+ return nil
722
+ end
723
+ elm=elm.values[1]
724
+ end
725
+ end
726
+
727
+ # if root, return true
728
+ #
729
+ # ルートの場合、trueを返す。
730
+ # xyml_tree.root.is_root?
731
+ # #-> true
732
+ # xyml_tree.root.gcfna('d','e','ggg').is_root?
733
+ # #-> false
734
+ def is_root?
735
+ self.values[1]==:_iamroot
736
+ end
737
+
738
+ # delete the self element from the child element array of its parent element.
739
+ #
740
+ # 自身のエレメントを、親エレメントの子エレメント配列から、削除する。
741
+ # ==== Return
742
+ # the deleted element, or nil if no parent element.
743
+ #
744
+ # 削除されたエレメント(もしくは、親エレメントが無い場合、"nil")
745
+ #
746
+ # xyml_tree.root.gcfna('d','e','ggg').dsl
747
+ # #-> [{a:[{b:'ccc'},{d:[{e:'fff'}]},{h:[{e:'fff'}]}]}]
748
+ def dsl
749
+ if parent=self.gp then
750
+ parent.values[0].each_with_index do |child,index|
751
+ if child==self then
752
+ parent.values[0].delete_at(index)
753
+ self._sp(nil)
754
+ return child
755
+ end
756
+ end
757
+ raise "something wrong. parent does not have me as a child."
758
+ end
759
+ nil
760
+ end
761
+
762
+ =begin
763
+ # I think this method is not necessary.
764
+ def dc element
765
+ self.values[0].each_with_index do |tchild,index|
766
+ if tchild==element then
767
+ parent.values[0].delete_at(index)
768
+ element._sp(nil)
769
+ return child
770
+ end
771
+ end
772
+ raise "something wrong. parent does not have an element as a child."
773
+
774
+ end
775
+ =end
776
+
777
+
778
+ end