回答編集履歴
3
テキスト修正
test
CHANGED
@@ -114,7 +114,9 @@
|
|
114
114
|
|
115
115
|
|
116
116
|
|
117
|
+
以下のような別解を考えました。
|
118
|
+
|
117
|
-
質問で問われている本題から離れてしまいます
|
119
|
+
(ただし、質問で問われている本題から離れてしまうと思うので、あくまで参考に留めて頂ければと思います)
|
118
120
|
|
119
121
|
|
120
122
|
|
@@ -270,13 +272,13 @@
|
|
270
272
|
|
271
273
|
|
272
274
|
|
273
|
-
|
275
|
+
上記のコードで、`Hash#to_xml` を再帰メソッドとして実装しているので
|
274
|
-
|
276
|
+
|
275
|
-
|
277
|
+
「結局手間としては同じでは?」とお思いになるかもしれませんが、
|
276
|
-
|
278
|
+
|
277
|
-
|
279
|
+
ハッシュをXMLにするメソッドも自分で書かなくても、
|
278
|
-
|
280
|
+
|
279
|
-
|
281
|
+
以下のようなgemがあります。
|
280
282
|
|
281
283
|
|
282
284
|
|
@@ -288,4 +290,14 @@
|
|
288
290
|
|
289
291
|
|
290
292
|
|
293
|
+
この別解で、何が言いたいかと言えば、与件を
|
294
|
+
|
295
|
+
「XMLのテキストノードへのパスを取得する」問題と置き換えれば、
|
296
|
+
|
297
|
+
自分で再帰メソッドを書く手間をかけなくても欲しい情報が得られるのでは?
|
298
|
+
|
299
|
+
ということでした。
|
300
|
+
|
301
|
+
|
302
|
+
|
291
303
|
ご参考になれば幸いです。
|
2
テキスト修正
test
CHANGED
@@ -270,4 +270,22 @@
|
|
270
270
|
|
271
271
|
|
272
272
|
|
273
|
+
※上記のコードで、`Hash#to_xml` を再帰メソッドとして実装しているので
|
274
|
+
|
275
|
+
「結局手間としては同じでは?」とお思いになるかもしれませんが、
|
276
|
+
|
277
|
+
ハッシュをXMLにするメソッドも自分で書かなくても、
|
278
|
+
|
279
|
+
以下のようなgemがあります。
|
280
|
+
|
281
|
+
|
282
|
+
|
283
|
+
- ActiveSupport::[CoreExtensions::Array::Conversions#to_xml](http://api.rubyonrails.org/v2.3/classes/ActiveSupport/CoreExtensions/Array/Conversions.html#M000784)
|
284
|
+
|
285
|
+
|
286
|
+
|
287
|
+
- [Gyoku](https://github.com/savonrb/gyoku)
|
288
|
+
|
289
|
+
|
290
|
+
|
273
291
|
ご参考になれば幸いです。
|
1
別解追加
test
CHANGED
@@ -105,3 +105,169 @@
|
|
105
105
|
|
106
106
|
|
107
107
|
参考になりましたら幸いです。
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
----
|
112
|
+
|
113
|
+
**追記**
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
質問で問われている本題から離れてしまいますが、次のような別解を考えました。
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
所与のハッシュ`sample_hash`は、構造的に次のXMLと等価です。
|
122
|
+
|
123
|
+
```xml
|
124
|
+
|
125
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
126
|
+
|
127
|
+
<root>
|
128
|
+
|
129
|
+
<nest1-1>value1-1</nest1-1>
|
130
|
+
|
131
|
+
<nest1-2>
|
132
|
+
|
133
|
+
<nest2-1>
|
134
|
+
|
135
|
+
<nest3-1a>26513</nest3-1a>
|
136
|
+
|
137
|
+
<nest3-1b>3</nest3-1b>
|
138
|
+
|
139
|
+
</nest2-1>
|
140
|
+
|
141
|
+
<nest2-2>
|
142
|
+
|
143
|
+
<nest3-2a>317829</nest3-2a>
|
144
|
+
|
145
|
+
<nest3-2b>50</nest3-2b>
|
146
|
+
|
147
|
+
</nest2-2>
|
148
|
+
|
149
|
+
</nest1-2>
|
150
|
+
|
151
|
+
</root>
|
152
|
+
|
153
|
+
```
|
154
|
+
|
155
|
+
ただしXMLにするためには、最上位のノードは1つなので、上記では
|
156
|
+
|
157
|
+
便宜的に `<root>` 要素をトップに追加しています。
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
XMLを扱う問題に置き換えれば、`value1-1` や `26513`は XMLのテキストノードで、
|
162
|
+
|
163
|
+
これらはXPath で `//text()` という指定でまとめて取得できます。
|
164
|
+
|
165
|
+
あとは、テキストノードのそれぞれについて、XPathを逆に求めれば、
|
166
|
+
|
167
|
+
テキストノードとそれに至るXPathの組を得ることができます。
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
この考えで作成したスクリプトが以下です。
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
|
177
|
+
# coding: utf-8
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
require 'nokogiri'
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
sample_hash =
|
186
|
+
|
187
|
+
{'nest1-1' => 'value1-1',
|
188
|
+
|
189
|
+
'nest1-2' =>
|
190
|
+
|
191
|
+
{
|
192
|
+
|
193
|
+
'nest2-1' => {
|
194
|
+
|
195
|
+
'nest3-1a' => '26513',
|
196
|
+
|
197
|
+
'nest3-1b' => '3'
|
198
|
+
|
199
|
+
},
|
200
|
+
|
201
|
+
'nest2-2' => {
|
202
|
+
|
203
|
+
'nest3-2a' => '317829',
|
204
|
+
|
205
|
+
'nest3-2b' => '50'
|
206
|
+
|
207
|
+
}
|
208
|
+
|
209
|
+
}
|
210
|
+
|
211
|
+
}
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
class Hash
|
216
|
+
|
217
|
+
def to_xml
|
218
|
+
|
219
|
+
map do |k, v|
|
220
|
+
|
221
|
+
text = Hash === v ? v.to_xml : v
|
222
|
+
|
223
|
+
'<%s>%s</%s>' % [k, text, k]
|
224
|
+
|
225
|
+
end.join
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
xml ='<?xml version="1.0" encoding="UTF-8"?><root>%s</root>' % [sample_hash.to_xml]
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
Nokogiri::XML(xml).xpath('//text()').each do |item|
|
238
|
+
|
239
|
+
xpath = Nokogiri::CSS.xpath_for item.css_path
|
240
|
+
|
241
|
+
puts '%s=%s' % [xpath[0], item]
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
```
|
246
|
+
|
247
|
+
上記では、XMLをパース(解析)するために、`nokogiri` を使っており、
|
248
|
+
|
249
|
+
このスクリプトを実行すると以下が表示されます。
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
> //root/nest1-1/child::text()=value1-1
|
254
|
+
|
255
|
+
//root/nest1-2/nest2-1/nest3-1a/child::text()=26513
|
256
|
+
|
257
|
+
//root/nest1-2/nest2-1/nest3-1b/child::text()=3
|
258
|
+
|
259
|
+
//root/nest1-2/nest2-2/nest3-2a/child::text()=317829
|
260
|
+
|
261
|
+
//root/nest1-2/nest2-2/nest3-2b/child::text()=50
|
262
|
+
|
263
|
+
|
264
|
+
|
265
|
+
このように与題をXMLのテキストノードの走査と考えて、`//text()` でテキストノードをまとめて
|
266
|
+
|
267
|
+
取ってこれるパーサーを使えば、自分で再帰的にテキストノードを探すメソッドを作らなくても
|
268
|
+
|
269
|
+
よくなります。
|
270
|
+
|
271
|
+
|
272
|
+
|
273
|
+
ご参考になれば幸いです。
|