ixyml 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+ vendor/bundle
18
+ *.swp
19
+
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ixyml.gemspec
4
+ gemspec
5
+
6
+ gem 'json'
7
+ gem 'test'
8
+ group :test do
9
+ gem 'unit'
10
+ gem 'shoulda'
11
+ end
12
+
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ixyml (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (4.0.0)
10
+ i18n (~> 0.6, >= 0.6.4)
11
+ minitest (~> 4.2)
12
+ multi_json (~> 1.3)
13
+ thread_safe (~> 0.1)
14
+ tzinfo (~> 0.3.37)
15
+ ansi (1.4.3)
16
+ atomic (1.1.13)
17
+ i18n (0.6.5)
18
+ json (1.8.0)
19
+ minitest (4.7.5)
20
+ multi_json (1.7.9)
21
+ rubytest (0.7.0)
22
+ ansi
23
+ shoulda (3.5.0)
24
+ shoulda-context (~> 1.0, >= 1.0.1)
25
+ shoulda-matchers (>= 1.4.1, < 3.0)
26
+ shoulda-context (1.1.5)
27
+ shoulda-matchers (2.3.0)
28
+ activesupport (>= 3.0.0)
29
+ test (1.0.0)
30
+ rubytest
31
+ thread_safe (0.1.2)
32
+ atomic
33
+ tzinfo (0.3.37)
34
+ unit (0.4.1)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ ixyml!
41
+ json
42
+ shoulda
43
+ test
44
+ unit
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ixyml.gemspec
4
+ gemspec
5
+
6
+ gem 'yaml'
7
+ gem 'json'
8
+ gem 'test'
9
+ group :test do
10
+ gem 'unit'
11
+ gem 'shoulda'
12
+ end
13
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Nobuhiko Ido
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Ixyml
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ixyml'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ixyml
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,8 @@
1
+ #! /usr/local/bin/ruby
2
+ require 'xyml/xyml'
3
+
4
+ from=ARGV[0]
5
+ xml_text=File.open(from).read
6
+ doc = REXML::Document.new xml_text
7
+ Xyml.dbg_dom_print_rcsv doc.root,0
8
+ doc.write(STDOUT,2)
data/bin/x2y ADDED
@@ -0,0 +1,8 @@
1
+ #! /usr/local/bin/ruby
2
+ require 'xyml/xyml'
3
+
4
+ from=ARGV[0]
5
+ to=ARGV[1]
6
+ xyml=Xyml::Document.new
7
+ xyml.load_XML(File.open(from))
8
+ xyml.out_YAML(File.open(to,'w'))
data/bin/y2x ADDED
@@ -0,0 +1,17 @@
1
+ #! /usr/local/bin/ruby
2
+ require 'xyml/xyml'
3
+
4
+ from=ARGV[0]
5
+ to=ARGV[1]
6
+ indent=nil
7
+ if ARGV[2]
8
+ indent=ARGV[2]
9
+ end
10
+
11
+ xyml=Xyml::Document.new
12
+ xyml.load_YAML(File.open(from))
13
+ if indent then
14
+ xyml.out_XML(File.open(to,'w'),indent)
15
+ else
16
+ xyml.out_XML(File.open(to,'w'))
17
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ixyml/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Nobuhiko Ido"]
6
+ gem.email = ["ido@gifu-keizai.ac.jp"]
7
+ gem.description = %q{I propose a new file format called "XYML." Xyml module has the following functions:
8
+ * loads a XYML file as an instance of Xyml::Document, saves an instance of Xyml::Document as a XYML file.
9
+ * loads an XML subset file as an instance of Xyml::Document, saves an instance of Xyml::Document as an XML file.
10
+ * saves an instance of Xyml::Document as a JSON file.
11
+ * converts an instance of Xyml::Document to an instance of REXML::Document and vice versa. The instance of REXML::Document supports a subset of XML specifications.
12
+ Xyml_element module provides XYML element API methods. These API methods can be used to elements in Xyml::Document.}
13
+ gem.summary = %q{XYML file accessors and XYML element accessors.}
14
+
15
+ gem.homepage = "https://github.com/nobuhiko-ido/Ixyml"
16
+
17
+ gem.files = `git ls-files`.split($\)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.name = "ixyml"
21
+ gem.require_paths = ["lib"]
22
+ gem.version = Ixyml::VERSION
23
+ end
@@ -0,0 +1,10 @@
1
+ require "ixyml/version"
2
+ require 'ixyml/xyml'
3
+ require 'ixyml/xyml_element'
4
+
5
+ # see Xyml module and Xyml_element module.
6
+ #
7
+ # Xymlモジュール、および、Xyml_elementモジュールを参照。
8
+ module Ixyml
9
+
10
+ end
@@ -0,0 +1,3 @@
1
+ module Ixyml
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,821 @@
1
+ require 'rexml/document'
2
+ require 'yaml'
3
+ require 'json'
4
+ require 'pp'
5
+ require_relative 'xyml_element'
6
+ # In this manual, "XYML" is explained first. After that, "XYML module" is explained.
7
+ #
8
+ # このマニュアルでは、最初にXYMLについて説明し、その後にXYMLモジュールについて説明する。
9
+ #
10
+ # == (1)XYML file format
11
+ # I propose an alternative text file format ”XYML(Xml in YaML format)” for writing XML subset data,
12
+ # suitable for input by non-engineers. Although some file formats have been proposed for the same purpose,
13
+ # XYML can be distinguished from them by its significant feature that a XYML format file can be read and
14
+ # written as a YAML file. Inheriting both the simple tree data structure of XML and the readability of YAML,
15
+ # a text in the XYML format is easy to understand because it looks like book contents.
16
+ #
17
+ # == (1)Xymlファイル形式
18
+ #
19
+ # 非技術者にも XML サブセットデータの入力が容易に行えることを目的とした、ファイル形式
20
+ # ”XYML(Xml in YaML format)”を提案する。このようなファイル形式は既にいくつもの提案があるが、
21
+ # 提案する XYML はデータ直列化形式である YAML ファイルとして読み書きが出来ることに大きな特徴がある。
22
+ # XML のツリー構造データの簡明さと YAML の可読性の良さとを活かすことにより、目次風の分かりやすい
23
+ # ファイル形式を XYML は実現している。
24
+ #
25
+ #
26
+ # == (2)Example of Mapping between XYML and XML
27
+ # == (2)XYMLとXMLとの対応の例
28
+ # +--XYML------------+ +--XML---------------+
29
+ # | - aaa: | | <aaa> |
30
+ # | - bbb: | | <bbb xxx="1" |
31
+ # | - xxx: 1 | | yyy="2"> |
32
+ # | - yyy: 2 | | <ccc zzz="3"> |
33
+ # | - ccc: | | morning |
34
+ # | - zzz: 3 | | </ccc> |
35
+ # | - morning | | <ddd zzz="4"> |
36
+ # | - ddd: | | noon |
37
+ # | - zzz: 4 | | </ddd> |
38
+ # | - noon | | </bbb> |
39
+ # | - eee: | | <eee xxx="5" |
40
+ # | - xxx: 5 | | yyy="6"> |
41
+ # | - yyy: 6 | | <fff zzz="7"> |
42
+ # | - fff: | | night |
43
+ # | - zzz: 7 | | </fff> |
44
+ # | - night | | </eee> |
45
+ # +------------------+ | </aaa> |
46
+ # +--------------------+
47
+ #
48
+ # == (3)Mapping from XML to XYML
49
+ #
50
+ # == (3)XMLからXYMLへの対応付け
51
+ #
52
+ # === (3.1)element
53
+ #
54
+ #
55
+ # An element corresponds to a hash which has only one pair of key and value,
56
+ # where the key stands for the element name and the value is an array of
57
+ # child elements and texts. Note the key must be a symbol.
58
+ #
59
+ #
60
+ # === (3.1)要素(エレメント)
61
+ #
62
+ #
63
+ # 要素は、キー・バリュー対が一つだけのハッシュに対応する。そのキーが要素名を
64
+ # 表し、そのバリューは子エレメントとテキストが要素の配列となる。要素名となる
65
+ # キーはシンボルであることに注意。
66
+ #
67
+ # +--XML--------------------+ +--XYML-------+
68
+ # | <eee a>bc</eee> | | - eee: | '-'(hyphon) before 'eee'
69
+ # | * a : attribute | | - a | stands for a part of array
70
+ # | * b,c : child node,text | | - b | that belongs to the parent
71
+ # +-------------------------+ | - c | element.
72
+ # +-------------+
73
+ #
74
+ #
75
+ # === (3.2)attribute
76
+ #
77
+ # An attribute corresponds to a hash which has only one pair of key and value,
78
+ # where the key stands for the attribute name and the value is a scalar of attribute
79
+ # value.
80
+ # A hash of an attribute can be distinguished from a hash of an element by the fact
81
+ # that its value is not an array. Note the key must be a symbol.
82
+ #
83
+ # === (3.2)属性
84
+ #
85
+ # 属性は、キー・バリュー対が一つだけのハッシュに対応する。そのキーが属性名を
86
+ # 表し、そのバリューが属性値を表す。
87
+ # バリューが配列では無いことにより、属性のハッシュは、要素のハッシュと見分けがつく。
88
+ # キーはシンボルであることに注意。
89
+ #
90
+ # +--XML--------------------+ +--XYML-------+ '-'(hyphon) before 'aaa'
91
+ # | aaa="AAA" | | - aaa: AAA | stands for a part of array
92
+ # | | | | that belongs to the parent
93
+ # +-------------------------+ +-------------+ element.
94
+ #
95
+ # === (3.3) text node
96
+ #
97
+ # A text node corresponds to a scalar which is in the array of its parent element.
98
+ #
99
+ # If two or more scalars are in the array, they are joined when method 'gt'(get text) is called.
100
+ # You can get such parted text stored in a array when designating :raw for the argument of method 'gt.'
101
+ # see Xyml_element module for 'gt' method
102
+ #
103
+ # === (3.3) テキストノード
104
+ #
105
+ # テキストは、親エレメントの配列に直接格納されるスカラーに対応する。
106
+ #
107
+ # 2つ以上のスカラーが配列内にある場合、エレメントの'gt'メソッドが呼び出された際に、それらは結合
108
+ # される。'gt'メソッドの引数に:rawを指定すると、配列に格納された分かち書きのテキストが得られる。
109
+ # (メソッド'gt'については、Xyml_elementモジュールを参照のこと)
110
+ #
111
+ # +--XML--------------------+ +--XYML-------+ '-'(hyphon) before 'TTT'
112
+ # | <...>TTT<...> | | - TTT | stands for a part of array
113
+ # | | | | that belongs to the parent
114
+ # +-------------------------+ +-------------+ element.
115
+ #
116
+ #
117
+ #
118
+ # ==(4) XYML module
119
+ # Xyml module has the following functions:
120
+ # * loads a XYML file to an instance of Xyml::Document, saves an instance of Xyml::Document to a XYML file.
121
+ # * loads an XML subset file to an instance of Xyml::Document, saves an instance of Xyml::Document to an XML file.
122
+ # * saves an instance of Xyml::Document to a JSON file.(You can load a JSON file as XYML file, because JSON is included in YAML as its flow style.)
123
+ # * converts an instance of Xyml::Document to an instance of REXML::Document and vice versa. Note an instance of REXML::Document in this case supports a subset of XML specifications, not full set.
124
+ # Instance methods of Xyml::Document class deal with only accesses to instance variables. Concrete procedures are written in Xyml module methods.
125
+ # In the figure below, Xyml module method names are enclosed in square brackets("[]").
126
+ #
127
+ # ==(4) XYMLモジュール
128
+ # 提案するファイル形式XYMLについて、Xymlモジュールは次の機能を持つ。
129
+ # * Xyml::Documentクラスのインスタンスとして、XYMLファイルをロード/出力する。
130
+ # * Xyml::Documentクラスのインスタンスとして、XMLサブセットのファイルをロード/出力する。
131
+ # * Xyml::Documentクラスのインスタンスとして、JSONファイルを出力する(JSONはYAMLのフロースタイルなので、入力はXYMLファイルとして行える)。
132
+ # * Xyml::DocumentクラスのインスタンスとREXML::Documentのインスタンスとの相互変換を行う(但し、REXML::Documentは仕様のフルセットでなく、サブセットに対応)。
133
+ # Xyml::Documentクラスのメソッドは、インスタンス変数に関わる処理のみを行い、具体的な処理はXymlモジュールメソッドに記述している。
134
+ # 下図中、モジュールメソッド名は"[]"(角型括弧)で囲んで表示している。
135
+ #
136
+ # +-------------------------+ load_XYML +------------------+
137
+ # | |[rawobj2element]| |
138
+ # | |<---------------| |
139
+ # | Xyml::Document | out_XYML | XYML file |
140
+ # | instance | [doc2file] |(YAML subset file)|
141
+ # | |--------------->| |
142
+ # | +-------------+ | +------------------+
143
+ # | | Raw Object | |
144
+ # | +-------------+ | out_JSON +------------------+
145
+ # | |--------------->| JSON subset file |
146
+ # +-------------------------+ +------------------+
147
+ # | | ^
148
+ # | to_domobj | |
149
+ # V [rawobj2domobj] | |[domboj2element]
150
+ # +-------------------|--|--+
151
+ # | | | | load_XML +------------------+
152
+ # | | +---<---------------| |
153
+ # | REXML::Document | | out_XML | XML subset file |
154
+ # | instance +--------------------->| |
155
+ # | | +------------------+
156
+ # +-------------------------+
157
+ #
158
+ #
159
+ # see also "Xyml_element module."
160
+ #
161
+ # 参考:Xyml_elementモジュール
162
+ #
163
+ module Xyml
164
+
165
+ # convert a tree composed of alternate hashes and arrays into a XYML element tree.
166
+ #
167
+ # ハッシュと配列とを交互に組み合わせたツリーを、XYMLエレメントのツリーに変換する。
168
+ # ==== Args
169
+ # _rawobj_ :: the root of a tree composed of alternate hashes and arrays
170
+ # ==== Return
171
+ # the root element of a created XYML element tree.
172
+ def self.rawobj2element rawobj
173
+ temp_root=Xyml::Element.new :tempRoot
174
+ Xyml.rawobj2element_rcsv rawobj,temp_root
175
+ temp_root[:tempRoot][0]._sp(:_iamroot)
176
+ temp_root[:tempRoot][0]
177
+ end
178
+
179
+ # convert a tree composed of alternate hashes and arrays into XML strings.
180
+ # note that a XYML element tree is such a tree to be converted by this method.
181
+ #
182
+ # ハッシュと配列とを交互に組み合わせたツリーを、XMLの文字列に変換する。
183
+ # XYMLエレメントのツリーも、このメソッドにより変換されるツリーとなっていることに注意。
184
+ # ==== Args
185
+ # _rawobj_ :: the root of a tree composed of alternate hashes and arrays.
186
+ # ==== Return
187
+ # strings in XML.
188
+ def self.rawobj2xmlString rawobj
189
+ sio=StringIO.new
190
+ Xyml.rawobj2domobj(rawobj).write(sio)
191
+ sio.rewind
192
+ sio.read
193
+ end
194
+
195
+ # convert a tree composed of alternate hashes and arrays into a DOM object tree.
196
+ # note that a XYML element tree is such a tree that can be converted by this method.
197
+ #
198
+ # ハッシュと配列とを交互に組み合わせたツリーを、DOMオブジェクトのツリーに変換する。
199
+ # XYMLエレメントのツリーも、このメソッドにより変換されるツリーとなっていることに注意。
200
+ # ==== Args
201
+ # _rawobj_ :: the root of a tree composed of alternate hashes and arrays.
202
+ #
203
+ # ==== Return
204
+ # an instance of REXML::Document.
205
+ def self.rawobj2domobj rawobj
206
+ dom = REXML::Document.new <<EOS
207
+ <?xml version='1.0' encoding='UTF-8'?>
208
+ EOS
209
+ Xyml.rawobj2domobj_rcsv rawobj,dom
210
+ end
211
+
212
+ # extend each hash in a tree composed of alternate hashes and arrays to a XYML element, and
213
+ # obtain a XYML element tree. This method is similar to _rawobj2element_ method except that _extend_element_
214
+ # does not create new hashes and arrays. In order to apply this method to a tree,
215
+ # all hashes in that tree must use symbols as hash keys.
216
+ #
217
+ # ハッシュと配列とを交互に組み合わせたツリー中のハッシュをXYMLエレメントに拡張し、
218
+ # XYMLエレメントツリーを得る。このメソッドは、 _rawobj2element_と似ているが、新たにハッシュと配列を
219
+ # 生成しない点が異なっている。このメソッドを適用するツリーでは、ハッシュのキーはすべてシンボルで
220
+ # なければならない。
221
+ # ==== Args
222
+ # _rawobj_ :: the root of a tree composed of alternate hashes and arrays
223
+ # ==== Return
224
+ # the root element of a created XYML element tree, which is identical to _rawobj_ in the input argument.
225
+ def self.extend_element rawobj
226
+ Xyml.extend_element_rcsv rawobj,nil
227
+ end
228
+
229
+ # convert a DOM object tree into a XYML element tree.
230
+ #
231
+ # DOMオブジェクトのツリーをXYMLエレメントのツリーに変換する。
232
+ # ==== Args
233
+ # _domobj_ :: an instance of REXML::Document.
234
+ # ==== Return
235
+ # the root element of a created XYML element tree.
236
+ #
237
+ # 生成されたXYMLエレメントツリーのルートエレメント
238
+ def self.domobj2element domobj
239
+ temproot=Hash.new
240
+ temproot.extend Xyml_element
241
+ Xyml.domobj2element_rcsv domobj,temproot,nil
242
+ end
243
+
244
+ # print out a XYML element tree to a XYML file.
245
+ #
246
+ # XYMLエレメントのツリーをXYMLファイルとしてプリントアウトする。
247
+ # ==== Args
248
+ # _doc_ :: an instance of Xyml::Document.
249
+ # _io_ :: output IO.
250
+ def self.doc2file doc,io
251
+ io.print "---\n"
252
+ Xyml.doc2file_rcsv(doc,0,io)
253
+
254
+ end
255
+
256
+ # Indent used in a YAML file. Two spaces.
257
+ #
258
+ # YAMLファイルとしてのインデント。スペース2個。
259
+ Indent=' '
260
+
261
+ # '- ' : String for sequence(Array) entry in a YAML file.
262
+ #
263
+ # '- ' : YAMLファイルのシーケンス(配列)要素を表す文字列
264
+ SequenceEntry='- '
265
+
266
+ # ': ' : String for mapping(hash) value in a YAML file.
267
+ #
268
+ # ': ' : YAMLファイルのマッピング(ハッシュ)の値を表す文字列
269
+ MappingValue=': '
270
+
271
+ # '| ' : String for literal block in a YAML file.
272
+ #
273
+ # '| ' : YAMLファイルのリテラルブロックを表す文字列
274
+ LiteralBlock='| '
275
+
276
+ # Xyml::Element class implement the element object in XYML tree data. See Xyml_element module
277
+ # for more detaled specifications.
278
+ #
279
+ # Xyml::Elementクラスは、XYMLツリーデータ中のエレメントを実装するクラスである。
280
+ # 詳細については、Xyml_elementモジュール参照。
281
+ class Element < Hash
282
+ include Xyml_element
283
+ # create an instance of Xyml::Element class.
284
+ #
285
+ # Xyml::Elementクラスのインスタンスを生成する。
286
+ # ==== Args
287
+ # _name_ :: Element name.
288
+ #
289
+ # _name_ :: エレメント名
290
+ def initialize name
291
+ name=name.intern unless name.is_a?(Symbol)
292
+ self[name]=Array.new
293
+ self
294
+ end
295
+ end
296
+
297
+ # Xyml::Document class implements the online data loaded from a XYML file.
298
+ # Because XYML is a subset of XML from the viewpoint of data structure, the data in this class
299
+ # is a tree composed of elements, attributes and texts. I call this tree "XYML element tree."
300
+ # The tree data in this class is composed of alternate hashes and arrays, in the same way of
301
+ # XYML files. See "Xyml module" for the mapping between XYML and XML.
302
+ #
303
+ # Xyml::Documentクラスは、XYMLファイルを読みだしたオンライン上のデータを実装するクラスである。
304
+ # XYMLファイルはデータ構造としてはXMLのサブセットであるため、Xyml::Documentクラスの保持する
305
+ # データは、エレメント・属性・テキストからなるツリーである。これを、XYMLエレメントツリーと呼ぶこととする。
306
+ # XYMLファイルフォーマットと同様に、このクラスによるツリーも、ハッシュと配列との交互の組み合わせ
307
+ # で実現されている。XYMLとXMLとの対応付けについては、"XYMLモジュール"を参照のこと。
308
+ # +-------------------------+ load_XYML +------------------+
309
+ # | |<-----------| |
310
+ # | Xyml::Document | out_XYML | XYML file |
311
+ # | instance |----------->|(YAML subset file)|
312
+ # | +-------------+ | +------------------+
313
+ # | | Raw Object | |
314
+ # | +-------------+ | out_JSON +------------------+
315
+ # | |----------->| JSON subset file |
316
+ # +-------------------------+ +------------------+
317
+ # | | ^
318
+ # | to_domobj | |
319
+ # V | |
320
+ # +-------------------|--|--+
321
+ # | | | | load_XML +------------------+
322
+ # | | +---<----------| |
323
+ # | REXML::Document | | out_XML | XML subset file |
324
+ # | instance +---------------->| |
325
+ # | | +------------------+
326
+ # +-------------------------+
327
+ class Document < Array
328
+
329
+ # the root of the XYML element tree. This root element is a hash extended by "Xyml_element module,"
330
+ # as all other XYML elements in the tree are also such hashes. The idential element to "@root" is stored
331
+ # in the begining of the array that this class inherites. Threrefore "@root" and "self.at(0)" stand
332
+ # for the same object. @root is provided for accessibility.
333
+ #
334
+ # XYMLエレメントツリーのルート。ツリー中の他のエレメントと同じく、このルートエレメントは
335
+ # "xyml_elementモジュール"により拡張されたハッシュである。@rootと同一のエレメントは、このクラスが
336
+ # 継承する配列の先頭にも格納されている。つまり、"@root"と"self.at(0)"とは同じオブジェクトを指す。
337
+ # "@root"は、アクセスしやすいように設けたものである。
338
+ attr_reader :root
339
+
340
+ # create an instance of Xyml::Document.
341
+ #
342
+ # Xyml::Documentのインスタンスを生成する。
343
+ # ==== Args
344
+ # if first argument in *_argv_ is designated:
345
+ #
346
+ # *_argv_の第一要素が指定されている場合:
347
+ # - case of a symbol
348
+ # - シンボルの場合
349
+ # - create an instance composed of only a root element such that the name of the root elemnemt is the first argument
350
+ # - ルート要素のみからなるインスタンスを生成。ルート要素の名前が、argvの第一要素となる。
351
+ #
352
+ # xyml_tree=Xyml::Document.new(:a)
353
+ # #-> [{a:[]}]
354
+ #
355
+ # - case of an IO instance
356
+ # - IOインスタンスの場合
357
+ # - create an instance corresponding to the XYML file loaded through the IO. note that only XYML file can be loaded, not XML.(use load_XML method to load an XML file.)
358
+ # - IOを通してロードしたXYMLファイルに対応したインスタンスを生成する。XYMLファイルのみが指定可能であり、XMLは不可であることに注意。(XMLファイルをロードする場合は、load_XMLメソッドを使用)
359
+ # # aaa.xyml
360
+ # # - a:
361
+ # # -b: ccc
362
+ # # -d:
363
+ # # - eee
364
+ # xyml_tree=Xyml::Document.new(File.open("aaa.xyml"))
365
+ # #-> [{a: [{b: "ccc"},{d: ["eee"]}]}]
366
+ #
367
+ # - case of a tree composed of alternate hashes and arrays.
368
+ # - 交互になったハッシュと配列とにより構成したツリーの場合
369
+ # - create an instance reflecting a input tree.
370
+ # - 入力引数のツリーを反映したインスタンスを生成。
371
+ # xyml_tree=Xyml::Document.new({a: [{b: "ccc"},{d: ["eee"]}]})
372
+ # #-> [{a: [{b: "ccc"},{d: ["eee"]}]}]
373
+ # xyml_tree.out_XYML(File.open("aaa.xyml","w"))
374
+ # #-> aaa.xyml
375
+ # # - a:
376
+ # # -b: ccc
377
+ # # -d:
378
+ # # - eee
379
+ def initialize *argv
380
+ if argv.size==1
381
+ if argv[0].is_a?(Symbol)
382
+ @root=Xyml::Element.new argv[0]
383
+ self.push @root
384
+ @root._sp(:_iamroot)
385
+ elsif argv[0].is_a?(IO)
386
+ raw_yaml=YAML.load(argv[0])
387
+ @root=Xyml.rawobj2element raw_yaml[0]
388
+ self.clear.push @root
389
+ @root._sp(:_iamroot)
390
+ elsif argv[0].is_a?(Hash)
391
+ @root=Xyml.rawobj2element argv[0]
392
+ self.clear.push @root
393
+ @root._sp(:_iamroot)
394
+ end
395
+ elsif argv.size>1
396
+ raise "tried to create Xyml::Document with more than one parameters."
397
+ end
398
+ end
399
+
400
+ # load an XML file through the designated IO and set the tree data in the file to the self.
401
+ #
402
+ # XMLファイルをIOよりロードして、そのツリーデータを自身に設定する。
403
+ # # aaa.xml
404
+ # # <a b="ccc">
405
+ # # <d>eee</d>
406
+ # # </a>
407
+ # xyml_tree=Xyml::Document.new
408
+ # xyml_tree.load_XML(File.open("aaa.xml"))
409
+ # #-> [{a: [{b: "ccc"},{d: ["eee"]}]}]
410
+ def load_XML io
411
+ xml=REXML::Document.new(io)
412
+ @root=Xyml.domobj2element xml.root
413
+ self.clear.push @root
414
+ @root._sp(:_iamroot)
415
+ io.close
416
+ end
417
+
418
+ # save an XML file corresponding to the tree data in the self through the designated IO.
419
+ #
420
+ # 自身のツリーデータを、指定されたIOを通して、XMLファイルに保存する。
421
+ # ==== Args
422
+ # _indent_(if not nil) :: a saved XML file is formatted with the designaged indent.
423
+ # xyml_tree=Xyml::Document.new({a: [{b: "ccc"},{d: ["eee"]}]})
424
+ # #-> [{a: [{b: "ccc"},{d: ["eee"]}]}]
425
+ # xyml_tree.out_XML(File.open("aaa.xml","w"))
426
+ # #-> aaa.xml
427
+ # # <a b="ccc">
428
+ # # <d>eee</d>
429
+ # # </a>
430
+ def out_XML io,indent=nil
431
+
432
+ if indent
433
+ Xyml.rawobj2domobj(@root).write(io,indent.to_i)
434
+ else
435
+ sio=StringIO.new
436
+ Xyml.rawobj2domobj(@root).write(sio)
437
+ sio.rewind
438
+ io.print sio.read,"\n"
439
+ end
440
+ io.close
441
+ end
442
+
443
+
444
+ # save a XYML file corresponding to the tree data in the self through the designated IO.
445
+ #
446
+ # 自身のツリーデータを、指定されたIOを通して、XYMLファイルに保存する。
447
+ # xyml_tree=Xyml::Document.new({a: [{b: "ccc"},{d: ["eee","fff"]}]})
448
+ # #-> [{a: [{b: "ccc"},{d: ["eee","fff"]}]}]
449
+ # xyml_tree.out_XYML(File.open("aaa.xyml","w"))
450
+ # #-> aaa.xyml
451
+ # # - a:
452
+ # # -b: ccc
453
+ # # -d:
454
+ # # - eee
455
+ # # - fff
456
+ def out_XYML io
457
+ Xyml.doc2file(self,io)
458
+ io.close
459
+ end
460
+
461
+ # save a XYML file corresponding to the tree data in the self through the designated IO,
462
+ # in the way that a saved XYML file is in the "standard syle."
463
+ # For example, a XYML file has no redandant partitions in texts in the "standard style."
464
+ # Two XYML files can be compared presicely if they are in the standard style.
465
+ #
466
+ # 自身のツリーデータを、指定されたIOを通して、"標準スタイル"で、XYMLファイルに保存する。
467
+ # 例えば、"標準スタイル"ではXYMLファイル内で冗長なテキストの分かち書きを行わない。
468
+ # 標準スタイルであれば、2つのファイルを正確に比較することが可能となる。
469
+ # xyml_tree=Xyml::Document.new({a: [{b: "ccc"},{d: ["eee","fff"]}]})
470
+ # #-> [{a: [{b: "ccc"},{d: ["eee","fff"]}]}]
471
+ # xyml_tree.out_XYML(File.open("aaa.xyml","w"))
472
+ # #-> aaa.xyml
473
+ # # - a:
474
+ # # -b: ccc
475
+ # # -d:
476
+ # # - eeefff
477
+ def out_XYML_standard io
478
+ io.print "---\n"
479
+ Xyml.out_xyml_rcsv_std(self,0,io)
480
+ io.close
481
+ end
482
+
483
+
484
+ # load an XYML file through the designated IO and set the tree data in the file to the self.
485
+ #
486
+ # XYMLファイルをIOよりロードして、そのツリーデータを自身に設定する。
487
+ # # aaa.xyml
488
+ # # - a:
489
+ # # -b: ccc
490
+ # # -d:
491
+ # # - eee
492
+ # xyml_tree=Xyml::Document.new
493
+ # xyml_tree.load_XYML(File.open("aaa.xyml"))
494
+ # #-> [{a: [{b: "ccc"},{d: ["eee"]}]}]
495
+ def load_XYML io
496
+ raw_yaml=YAML.load(io)
497
+ @root=Xyml.rawobj2element raw_yaml[0]
498
+ self.clear.push @root
499
+ io.close
500
+ end
501
+
502
+ # save a JSON file corresponding to the tree data in the self through the designated IO.
503
+ # Note that a JSON file can be loaded by load_XYML method because JSON is a part of YAML.
504
+ #
505
+ # 自身のツリーデータを、指定されたIOを通して、JSONファイルに保存する。JSONファイルのロードは、
506
+ # _load_XYML_メソッドで実施できることに注意(JSONはYAML仕様の一部分となっているため)。
507
+ # xyml_tree=Xyml::Document.new({a: [{b: "ccc"},{d: ["eee"]}]})
508
+ # #-> [{a: [{b: "ccc"},{d: ["eee"]}]}]
509
+ # xyml_tree.out_JSON(File.open("aaa.json","w"))
510
+ # #-> aaa.jdon
511
+ # # [{"a":[{"b":"ccc"},{"d":["eee"]}]}]
512
+ def out_JSON io
513
+ serialized=JSON.generate(Xyml.remove_parent_rcsv(self))
514
+ io.print serialized
515
+ io.close
516
+ end
517
+
518
+ # convert the tree data in the self into a REXML::Document instance.
519
+ #
520
+ # 自身のツリーデータを、REXML::Documentインスタンスに変換する。
521
+ # ==== Return
522
+ # a REXML::Document instance.
523
+ # xyml_tree=Xyml::Document.new({a: [{b: "ccc"},{d: ["eee"]}]})
524
+ # REXML::Document rexml_tree=xyml_tree.to_domobj
525
+ def to_domobj
526
+ Xyml.rawobj2domobj(@root)
527
+ end
528
+
529
+ end # end of Xyml::Document
530
+
531
+ private
532
+
533
+ def self.rawobj2domobj_rcsv obj,dom
534
+ if obj.is_a?(Hash)
535
+ raise "loaded XYML document is illegal(ruby object contains a hash with no pairs)." if obj.length==0
536
+ raise "loaded XYML document is illegal(ruby object contains a hash where second key is not ':_parent' or ':__parent'). second key=#{obj.keys[1]}" if obj.length>1 && (obj.keys[1]!=:_parent && obj.keys[1]!=:__parent)
537
+ key=obj.keys[0]
538
+ value=obj[key]
539
+ if value.is_a?(Array)
540
+ elm=REXML::Element::new("#{key}")
541
+ dom.add_element(elm)
542
+ if value.length==0
543
+ return
544
+ end
545
+ step=:s0_attribute
546
+ value.each do |tobj|
547
+ case step
548
+
549
+ when :s0_attribute
550
+ if tobj.is_a?(Hash)
551
+ raise "loaded XYML document is illegal(ruby object contains a hash with no pairs) parent=#{key}." if tobj.length==0
552
+ raise "loaded XYML document is illegal(ruby object contains a hash where second key is not 'parent'). second key=#{tobj.keys[1]}" if tobj.length>1 && (tobj.keys[1]!=:_parent && tobj.keys[1]!=:__parent)
553
+ #puts "class=#{tobj.values[0].class}, to_s=#{tobj.values[0].to_s}"
554
+ if !tobj.values[0].is_a?(Array) && !tobj.values[0].is_a?(Hash)
555
+ elm.attributes["#{tobj.keys[0].to_s}"]="#{tobj.values[0].to_s}"
556
+ else
557
+ step=:s1_others
558
+ redo
559
+ end
560
+ else
561
+ step=:s1_others
562
+ redo
563
+ end
564
+
565
+ when :s1_others
566
+ if tobj.is_a?(Hash)
567
+ rawobj2domobj_rcsv tobj,elm
568
+ elsif tobj.is_a?(Array)
569
+ else
570
+ elm.add_text(tobj.to_s)
571
+ end
572
+
573
+ else
574
+ end
575
+ end
576
+ end
577
+ elsif obj.is_a?(Array)
578
+ raise "loaded XYML document is illegal(Array apear on the top)."
579
+ end
580
+ dom
581
+ end
582
+
583
+
584
+ def self.rawobj2element_rcsv(raw_obj,node)
585
+ if raw_obj.is_a?(Hash)
586
+ raise "loaded XYML document is illegal(ruby object contains a hash with no pairs)." if raw_obj.length==0
587
+ raise "loaded XYML document is illegal(ruby object contains a hash with more than one pair). first key=#{obj.keys[0]}" if raw_obj.length>1
588
+ key=raw_obj.keys[0]
589
+ value=raw_obj[key]
590
+ if value.is_a?(Array)
591
+ elm=Xyml::Element.new("#{key}")
592
+ node.ac elm
593
+ if value.length==0
594
+ return
595
+ end
596
+ step=:s0_attribute
597
+ value.each do |tobj|
598
+ case step
599
+ when :s0_attribute
600
+ if tobj.is_a?(Hash)
601
+ raise "loaded XYML document is illegal(ruby object contains a hash with no pairs) parent=#{key}." if tobj.length==0
602
+ raise "loaded XYML document is illegal(ruby object contains a hash with more than one pair). first key=#{tobj.keys[0]}" if tobj.length>1
603
+ if !tobj.values[0].is_a?(Array) && !tobj.values[0].is_a?(Hash)
604
+ elm.sa tobj.keys[0].to_s.intern,tobj.values[0].to_s
605
+ else
606
+ step=:s1_others
607
+ redo
608
+ end
609
+ else
610
+ step=:s1_others
611
+ redo
612
+ end
613
+
614
+ when :s1_others
615
+ if tobj.is_a?(Hash)
616
+ rawobj2element_rcsv tobj,elm
617
+ elsif tobj.is_a?(Array)
618
+ else
619
+ elm.at tobj.to_s unless tobj.to_s.empty?
620
+ end
621
+
622
+ else
623
+ end
624
+ end
625
+ end
626
+ elsif raw_obj.is_a?(Array)
627
+ raise "loaded XYML document is illegal(Array apear on the top)."
628
+ end
629
+ node
630
+ end
631
+
632
+ def self.extend_element_rcsv obj,parent
633
+ if obj.is_a?(Hash)
634
+ raise "ruby object is illegal(ruby object contains a hash with no pairs)." if obj.length==0
635
+ raise "ruby object is illegal(ruby object contains a hash with more than one pair). first key=#{obj.keys[0]}" if obj.length>1
636
+ raise "ruby hash has a key that is not a symbol. keys[0]=#{obj.keys[0]}" unless obj.keys[0].is_a?(Symbol)
637
+ value=obj[obj.keys[0]]
638
+ if value.is_a?(Array)
639
+ value.delete(nil)
640
+ obj.extend Xyml_element
641
+ obj._sp(parent)
642
+ if value.length==0
643
+ return
644
+ end
645
+ step=:s0_attribute
646
+ value.each do |tobj|
647
+ case step
648
+ when :s0_attribute
649
+ if tobj.is_a?(Hash)
650
+ raise "loaded XYML document is illegal(ruby object contains a hash with no pairs) parent=#{key}." if tobj.length==0
651
+ raise "loaded XYML document is illegal(ruby object contains a hash with more than one pair). first key=#{tobj.keys[0]}" if tobj.length>1
652
+ if !tobj.values[0].is_a?(Array) && !tobj.values[0].is_a?(Hash)
653
+ raise "ruby hash has a key that is not a symbol. keys[0]=#{tobj.keys[0]}" unless tobj.keys[0].is_a?(Symbol)
654
+ else
655
+ step=:s1_others
656
+ redo
657
+ end
658
+ else
659
+ step=:s1_others
660
+ redo
661
+ end
662
+
663
+ when :s1_others
664
+ if tobj.is_a?(Hash)
665
+ extend_element_rcsv tobj,obj
666
+ elsif tobj.is_a?(Array)
667
+ else
668
+ end
669
+
670
+ else
671
+ end
672
+ end
673
+ end
674
+ elsif obj.is_a?(Array)
675
+ raise "ruby object is illegal(Array apear on the top)."
676
+ end
677
+ obj
678
+ end
679
+
680
+ def self.domobj2element_rcsv elm,robj,parent
681
+ if elm.is_a?(REXML::Element)
682
+ elmArray=Array.new
683
+ robj[elm.expanded_name.to_sym]=elmArray
684
+ robj._sp(parent)
685
+ #p "#D#xyml.rb:domobj2element_rcsv:robj:";pp robj
686
+ if elm.has_attributes?
687
+ elm.attributes.each do |key,value|
688
+ attrHash=Hash.new
689
+ attrHash[key.to_sym]=value
690
+ elmArray.push(attrHash)
691
+ end
692
+ end
693
+ elm.each do |node|
694
+ if node.is_a?(REXML::Element)
695
+ elmHash=Hash.new
696
+ elmHash.extend Xyml_element
697
+ domobj2element_rcsv(node,elmHash,robj)
698
+ elmArray.push(elmHash)
699
+ elsif node.is_a?(REXML::Text)
700
+ text=node.to_s.gsub('&lt;','<').gsub('&gt;','>').gsub('&apos;','\'').gsub('&quot;','"').gsub('&amp;','&')
701
+ elmArray.push(text) if text.length!=0
702
+ else
703
+ end
704
+ end
705
+ end
706
+ robj
707
+ end
708
+
709
+ def self.doc2file_rcsv obj, nest, io
710
+ if obj.is_a?(Hash)
711
+ key=obj.keys[0]
712
+ value=obj.values[0]
713
+ if value.is_a?(Array)
714
+ io.print(Indent*nest,SequenceEntry,key.to_s.strip,":\n")
715
+ Xyml.doc2file_rcsv(value,nest+1,io)
716
+ else
717
+ io.print(Indent*nest,SequenceEntry, key.to_s.strip,MappingValue,Xyml.escaped_line(value.to_s),"\n")
718
+ end
719
+ elsif obj.is_a?(Array)
720
+ obj.each do |value|
721
+ if value.is_a?(Hash)
722
+ doc2file_rcsv(value,nest,io,)
723
+ elsif value.is_a?(Array)
724
+ else
725
+ io.print(Indent*nest, SequenceEntry, escaped_line(value.to_s),"\n")
726
+ end
727
+ end
728
+ if obj.length==0
729
+ io.print(Indent*nest,SequenceEntry, "\n")
730
+ end
731
+ else
732
+ end
733
+ end
734
+
735
+ def self.escaped_line(str)
736
+ escape_needed=false
737
+ if str.match(/\"|[:]\s|\s[#]|\A[,\[\]\{\}#&\*\!\|\>\<\%\s\@:'`]|\A[\?:-]\z|[:]\z|\n/)
738
+ "\""+str.gsub(/\\/,"\\\\\\\\").gsub(/\n/,"\\n").gsub(/\f/,"\\f").gsub(/\"/,'\"')+"\""
739
+ else
740
+ str
741
+ end
742
+ end
743
+
744
+ def self.out_xyml_rcsv_std obj, nest, io
745
+ if obj.is_a?(Hash)
746
+ key=obj.keys[0]
747
+ value=obj[key]
748
+ if value.is_a?(Array)
749
+ io.print(Indent*nest,SequenceEntry,key.to_s.strip,":\n")
750
+ out_xyml_rcsv_std(value,nest+1,io)
751
+ else
752
+ io.print(Indent*nest,SequenceEntry, key.to_s.strip,MappingValue,value.to_s.strip,"\n")
753
+ end
754
+ elsif obj.is_a?(Array)
755
+ unseparatedString=""
756
+ obj.each do |value|
757
+ if value.is_a?(Hash)
758
+ if unseparatedString.length!=00
759
+ io.print(Indent*nest, SequenceEntry, Xyml.escaped_line(unseparatedString), "\n")
760
+ unseparatedString="";
761
+ end
762
+ Xyml.out_xyml_rcsv_std(value,nest,io,)
763
+ elsif value.is_a?(Array)
764
+ else
765
+ unseparatedString+=value.to_s
766
+ end
767
+ end
768
+ if unseparatedString.length!=0
769
+ io.print(Indent*nest, SequenceEntry, escaped_line(unseparatedString),"\n")
770
+ unseparatedString="";
771
+ end
772
+ if obj.length==0
773
+ io.print(Indent*nest,SequenceEntry, "\n")
774
+ end
775
+ else
776
+ end
777
+ end
778
+
779
+
780
+ def self.remove_parent_rcsv elmArray
781
+ raise "something wrong when removing parent information from objects. elmArray=#{elmArray.inspect}" unless elmArray.is_a?(Array)
782
+ elmArray.each do |obj|
783
+ if(obj.is_a?(Hash))
784
+ if(obj.values[0].is_a?(Array))
785
+ obj._dp
786
+ remove_parent_rcsv obj.values[0]
787
+ end
788
+ end
789
+ end
790
+ elmArray
791
+ end
792
+
793
+ def self.dbg_dom_print_rcsv elem,nest
794
+ indent="||"
795
+ print "================================\n"
796
+ print indent*nest + "name : #{elem.name}\n"
797
+ attrs = elem.attributes
798
+ attrs.each{|a,e|
799
+ print indent*nest + "attr :#{a}=#{e}\n"
800
+ }
801
+ print indent*nest + "text : \n-->#{elem.text.to_s.gsub("\s",'_').gsub("\t",'\t')}<--\n"
802
+
803
+ elem.each do |node|
804
+ if node.is_a?(REXML::Element)
805
+ dbg_dom_print_rcsv node,nest+1
806
+ elsif node.is_a?(REXML::Text)
807
+ text=node.to_s.strip
808
+ print indent*nest + "textnode : \n-->#{text.gsub("\s",'_').gsub("\t",'\t')}<--\n"
809
+ end
810
+ end
811
+
812
+
813
+ if elem.has_elements? then
814
+ elem.each_element{|e|
815
+ dbg_dom_print_rcsv e,nest+1
816
+ }
817
+ end
818
+ end
819
+
820
+
821
+ end