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,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