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.
- data/.gitignore +19 -0
- data/.gitignore~ +17 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +44 -0
- data/Gemfile~ +13 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bin/dbg_x2o +8 -0
- data/bin/x2y +8 -0
- data/bin/y2x +17 -0
- data/ixyml.gemspec +23 -0
- data/lib/ixyml.rb +10 -0
- data/lib/ixyml/version.rb +3 -0
- data/lib/ixyml/xyml.rb +821 -0
- data/lib/ixyml/xyml_element.rb +778 -0
- data/test/dirTemp/ktest00.nml.j2j.json +1 -0
- data/test/dirTemp/ktest00.nml.nml.xml +53 -0
- data/test/dirTemp/ktest00.nml.nml.yaml +74 -0
- data/test/dirTemp/ktest00.nml.x2j.json +1 -0
- data/test/dirTemp/ktest00.nml.x2x.xml +53 -0
- data/test/dirTemp/ktest00.nml.xyj.yaml +134 -0
- data/test/dirTemp/ktest00.nml.xyx.xml +53 -0
- data/test/dirTemp/ktest00.nml.xyx.yaml +134 -0
- data/test/dirTemp/ktest00.nml.y2j.json +1 -0
- data/test/dirTemp/ktest00.nml.y2y.yaml +74 -0
- data/test/dirTemp/ktest00.nml.yxy.xml +2 -0
- data/test/dirTemp/ktest00.nml.yxy.yaml +74 -0
- data/test/dirTemp/ktest01.nml.yaml +74 -0
- data/test/dirTemp/ktest01.yxy.xml +2 -0
- data/test/dirTemp/ktest01.yxy.yaml +74 -0
- data/test/dirTemp/test01.nml.nml.xml +21 -0
- data/test/dirTemp/test01.nml.nml.yaml +5 -0
- data/test/dirTemp/test01.nml.x2j.json +1 -0
- data/test/dirTemp/test01.nml.x2x.xml +21 -0
- data/test/dirTemp/test01.nml.xyj.yaml +18 -0
- data/test/dirTemp/test01.nml.xyx.xml +21 -0
- data/test/dirTemp/test01.nml.xyx.yaml +18 -0
- data/test/dirTemp/test01.nml.y2j.json +1 -0
- data/test/dirTemp/test01.nml.y2y.yaml +5 -0
- data/test/dirTemp/test01.nml.yaml +74 -0
- data/test/dirTemp/test01.nml.yxy.xml +3 -0
- data/test/dirTemp/test01.nml.yxy.yaml +5 -0
- data/test/dirTemp/test01.yxy.xml +2 -0
- data/test/dirTemp/test01.yxy.yaml +74 -0
- data/test/dirTemp/testBreak.nml.yaml +7 -0
- data/test/dirTemp/testBreak.yxy.xml +5 -0
- data/test/dirTemp/testBreak.yxy.yaml +7 -0
- data/test/dirTemp/testCDATA.nml.nml.xml +26 -0
- data/test/dirTemp/testCDATA.nml.x2j.json +1 -0
- data/test/dirTemp/testCDATA.nml.x2x.xml +26 -0
- data/test/dirTemp/testCDATA.nml.xyj.yaml +18 -0
- data/test/dirTemp/testCDATA.nml.xyx.xml +26 -0
- data/test/dirTemp/testCDATA.nml.xyx.yaml +18 -0
- data/test/dirTemp/testCDATA.nml.y2j.json +1 -0
- data/test/dirTemp/testEscape.nml.nml.xml +77 -0
- data/test/dirTemp/testEscape.nml.nml.yaml +53 -0
- data/test/dirTemp/testEscape.nml.x2j.json +1 -0
- data/test/dirTemp/testEscape.nml.x2x.xml +77 -0
- data/test/dirTemp/testEscape.nml.xyj.yaml +213 -0
- data/test/dirTemp/testEscape.nml.xyx.xml +77 -0
- data/test/dirTemp/testEscape.nml.xyx.yaml +213 -0
- data/test/dirTemp/testEscape.nml.y2j.json +1 -0
- data/test/dirTemp/testEscape.nml.y2y.yaml +53 -0
- data/test/dirTemp/testEscape.nml.yxy.xml +2 -0
- data/test/dirTemp/testEscape.nml.yxy.yaml +53 -0
- data/test/dirTemp/testNS.nml.nml.xml +21 -0
- data/test/dirTemp/testNS.nml.x2j.json +1 -0
- data/test/dirTemp/testNS.nml.x2x.xml +21 -0
- data/test/dirTemp/testNS.nml.xyj.yaml +19 -0
- data/test/dirTemp/testNS.nml.xyx.xml +21 -0
- data/test/dirTemp/testNS.nml.xyx.yaml +19 -0
- data/test/dirTemp/testNS.nml.y2j.json +1 -0
- data/test/test_xyml.rb +167 -0
- data/test/test_xyml.rb~ +167 -0
- data/test/test_xyml_element.rb +241 -0
- data/test/test_xyml_element.rb~ +111 -0
- data/test/testfiles/ktest00.nml.ori.json +1 -0
- data/test/testfiles/ktest00.nml.ori.xml +53 -0
- data/test/testfiles/ktest00.nml.ori.yaml +74 -0
- data/test/testfiles/ktest00.nml.ori.yaml~ +75 -0
- data/test/testfiles/ktest01.ori.yaml +75 -0
- data/test/testfiles/test01.nml.ori.xml +21 -0
- data/test/testfiles/test01.nml.ori.yaml +5 -0
- data/test/testfiles/test01.ori.yaml +75 -0
- data/test/testfiles/testBreak.ori.yaml +10 -0
- data/test/testfiles/testCDATA.ng.ng.xml +26 -0
- data/test/testfiles/testEscape.nml.ori.xml +77 -0
- data/test/testfiles/testEscape.nml.ori.yaml +105 -0
- data/test/testfiles/testNS.nml.ori.xml +21 -0
- data/test/testfiles/xmlTemp.xml +2 -0
- data/test/testfiles/xymlTemp.xyml +6 -0
- 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
|