回答編集履歴
3
テキスト修正
answer
CHANGED
@@ -56,7 +56,8 @@
|
|
56
56
|
----
|
57
57
|
**追記**
|
58
58
|
|
59
|
+
以下のような別解を考えました。
|
59
|
-
質問で問われている本題から離れてしま
|
60
|
+
(ただし、質問で問われている本題から離れてしまうと思うので、あくまで参考に留めて頂ければと思います)
|
60
61
|
|
61
62
|
所与のハッシュ`sample_hash`は、構造的に次のXMLと等価です。
|
62
63
|
```xml
|
@@ -134,13 +135,18 @@
|
|
134
135
|
取ってこれるパーサーを使えば、自分で再帰的にテキストノードを探すメソッドを作らなくても
|
135
136
|
よくなります。
|
136
137
|
|
137
|
-
|
138
|
+
上記のコードで、`Hash#to_xml` を再帰メソッドとして実装しているので
|
138
|
-
|
139
|
+
「結局手間としては同じでは?」とお思いになるかもしれませんが、
|
139
|
-
|
140
|
+
ハッシュをXMLにするメソッドも自分で書かなくても、
|
140
|
-
|
141
|
+
以下のようなgemがあります。
|
141
142
|
|
142
143
|
- ActiveSupport::[CoreExtensions::Array::Conversions#to_xml](http://api.rubyonrails.org/v2.3/classes/ActiveSupport/CoreExtensions/Array/Conversions.html#M000784)
|
143
144
|
|
144
145
|
- [Gyoku](https://github.com/savonrb/gyoku)
|
145
146
|
|
147
|
+
この別解で、何が言いたいかと言えば、与件を
|
148
|
+
「XMLのテキストノードへのパスを取得する」問題と置き換えれば、
|
149
|
+
自分で再帰メソッドを書く手間をかけなくても欲しい情報が得られるのでは?
|
150
|
+
ということでした。
|
151
|
+
|
146
152
|
ご参考になれば幸いです。
|
2
テキスト修正
answer
CHANGED
@@ -134,4 +134,13 @@
|
|
134
134
|
取ってこれるパーサーを使えば、自分で再帰的にテキストノードを探すメソッドを作らなくても
|
135
135
|
よくなります。
|
136
136
|
|
137
|
+
※上記のコードで、`Hash#to_xml` を再帰メソッドとして実装しているので
|
138
|
+
「結局手間としては同じでは?」とお思いになるかもしれませんが、
|
139
|
+
ハッシュをXMLにするメソッドも自分で書かなくても、
|
140
|
+
以下のようなgemがあります。
|
141
|
+
|
142
|
+
- ActiveSupport::[CoreExtensions::Array::Conversions#to_xml](http://api.rubyonrails.org/v2.3/classes/ActiveSupport/CoreExtensions/Array/Conversions.html#M000784)
|
143
|
+
|
144
|
+
- [Gyoku](https://github.com/savonrb/gyoku)
|
145
|
+
|
137
146
|
ご参考になれば幸いです。
|
1
別解追加
answer
CHANGED
@@ -51,4 +51,87 @@
|
|
51
51
|
nest1-2/nest2-2/nest3-2b: 50
|
52
52
|
|
53
53
|
|
54
|
-
参考になりましたら幸いです。
|
54
|
+
参考になりましたら幸いです。
|
55
|
+
|
56
|
+
----
|
57
|
+
**追記**
|
58
|
+
|
59
|
+
質問で問われている本題から離れてしまいますが、次のような別解を考えました。
|
60
|
+
|
61
|
+
所与のハッシュ`sample_hash`は、構造的に次のXMLと等価です。
|
62
|
+
```xml
|
63
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
64
|
+
<root>
|
65
|
+
<nest1-1>value1-1</nest1-1>
|
66
|
+
<nest1-2>
|
67
|
+
<nest2-1>
|
68
|
+
<nest3-1a>26513</nest3-1a>
|
69
|
+
<nest3-1b>3</nest3-1b>
|
70
|
+
</nest2-1>
|
71
|
+
<nest2-2>
|
72
|
+
<nest3-2a>317829</nest3-2a>
|
73
|
+
<nest3-2b>50</nest3-2b>
|
74
|
+
</nest2-2>
|
75
|
+
</nest1-2>
|
76
|
+
</root>
|
77
|
+
```
|
78
|
+
ただしXMLにするためには、最上位のノードは1つなので、上記では
|
79
|
+
便宜的に `<root>` 要素をトップに追加しています。
|
80
|
+
|
81
|
+
XMLを扱う問題に置き換えれば、`value1-1` や `26513`は XMLのテキストノードで、
|
82
|
+
これらはXPath で `//text()` という指定でまとめて取得できます。
|
83
|
+
あとは、テキストノードのそれぞれについて、XPathを逆に求めれば、
|
84
|
+
テキストノードとそれに至るXPathの組を得ることができます。
|
85
|
+
|
86
|
+
この考えで作成したスクリプトが以下です。
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
# coding: utf-8
|
90
|
+
|
91
|
+
require 'nokogiri'
|
92
|
+
|
93
|
+
sample_hash =
|
94
|
+
{'nest1-1' => 'value1-1',
|
95
|
+
'nest1-2' =>
|
96
|
+
{
|
97
|
+
'nest2-1' => {
|
98
|
+
'nest3-1a' => '26513',
|
99
|
+
'nest3-1b' => '3'
|
100
|
+
},
|
101
|
+
'nest2-2' => {
|
102
|
+
'nest3-2a' => '317829',
|
103
|
+
'nest3-2b' => '50'
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
class Hash
|
109
|
+
def to_xml
|
110
|
+
map do |k, v|
|
111
|
+
text = Hash === v ? v.to_xml : v
|
112
|
+
'<%s>%s</%s>' % [k, text, k]
|
113
|
+
end.join
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
xml ='<?xml version="1.0" encoding="UTF-8"?><root>%s</root>' % [sample_hash.to_xml]
|
118
|
+
|
119
|
+
Nokogiri::XML(xml).xpath('//text()').each do |item|
|
120
|
+
xpath = Nokogiri::CSS.xpath_for item.css_path
|
121
|
+
puts '%s=%s' % [xpath[0], item]
|
122
|
+
end
|
123
|
+
```
|
124
|
+
上記では、XMLをパース(解析)するために、`nokogiri` を使っており、
|
125
|
+
このスクリプトを実行すると以下が表示されます。
|
126
|
+
|
127
|
+
> //root/nest1-1/child::text()=value1-1
|
128
|
+
//root/nest1-2/nest2-1/nest3-1a/child::text()=26513
|
129
|
+
//root/nest1-2/nest2-1/nest3-1b/child::text()=3
|
130
|
+
//root/nest1-2/nest2-2/nest3-2a/child::text()=317829
|
131
|
+
//root/nest1-2/nest2-2/nest3-2b/child::text()=50
|
132
|
+
|
133
|
+
このように与題をXMLのテキストノードの走査と考えて、`//text()` でテキストノードをまとめて
|
134
|
+
取ってこれるパーサーを使えば、自分で再帰的にテキストノードを探すメソッドを作らなくても
|
135
|
+
よくなります。
|
136
|
+
|
137
|
+
ご参考になれば幸いです。
|