« 価格.comのサイト閉鎖は遅すぎ? | メイン | 「価格.com」事件,「当社に過失はなかった」とカカクコム社長 »
2005年05月17日
Ruby の正規表現によるXMLの解析: force_arrayオプション
Ruby の正規表現によるXMLの解析のECS.xml_to_hash は、リスト要素にも対応しています。同じ要素が複数あらわれる場合には、それは自動的に配列に変換されます。
しかし、複数あらわれる可能性のある要素が、たまたま一個しかなかった場合、ECS.xml_to_hashは配列には変換しません。よって、変換後の処理で、オブジェクトが Array か String かを調べて分岐する必要があります。
これをいちいちやっていては手間もかかるし美しくないので、ECS.xml_to_hash に force_array オプションを追加してみました。名前はPerlのXML::SimpleにあるForceArrayオプションからとっています。
使い方は、例えば以下のようになります。
hash = ECS.xml_to_hash xml_str, 'Offer'=>true, 'Author'=>true, 'Actor'=>trueあるいは、
hash = ECS.xml_to_hash xml_str, ['Offer', 'Author', 'Actor']
指定した要素名の要素は、ひとつしか存在しなくても必ず配列に変換されます。
1| TAG_STR = %q{<[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$(?!\n))} #' 2| COMMENT_STR = %q{<!(?:--[^-]*-(?:[^-]+-)*?-(?:[^>-]*(?:-[^>-]+)*?)??)*(?:>|$(?!\n)|--.*$)} 3| CDATA_STR = %q{<!\[CDATA\[.*?(?:\]\]>|$(?!\n))} 4| TEXT_STR = "[^<]*" 5| XRE = Regexp.new "(#{TEXT_STR})(#{CDATA_STR}|#{COMMENT_STR}|#{TAG_STR})", 6| 0, 'u' 7| def ECS.xml_to_hash xml_str, forse_array=nil 8| if forse_array.kind_of? Array 9| forse_array_hash = 10| Hash[*(forse_array.zip(Array.new(forse_array.size, true))).flatten] 11| elsif forse_array.kind_of? Hash 12| forse_array_hash = forse_array 13| else 14| forse_array_hash = {} 15| end 16| hash = {} 17| stack = [] 18| thash = hash 19| 20| text = nil 21| tag = nil 22| tagname = nil 23| phash = nil 24| pobj = nil 25| xml_str.scan(XRE) {|text, tag| 26| if tag =~ /^<\s*(\w[^\s>]*)/ 27| tagname = $1 28| stack.push thash 29| thash = {} 30| elsif tag =~ %r{^<\s*/\s*(\w[^\s>]*)} 31| tagname = $1 32| phash = stack.pop 33| pobj = thash.empty? ? text : thash 34| if thash.empty? 35| pobj = text 36| else 37| pobj = thash 38| end 39| if phash[tagname] 40| unless phash[tagname].kind_of? Array 41| phash[tagname] = [phash[tagname]] 42| end 43| phash[tagname].push pobj 44| else 45| if forse_array_hash[tagname] 46| phash[tagname] = [pobj] 47| else 48| phash[tagname] = pobj 49| end 50| end 51| thash = phash 52| end 53| } 54| hash 55| end
投稿者 tam : 2005年05月17日 10:49
コメント
tam様
アマゾン ジャパンの吉松です。遅まきながらtamさんのBrowseNodeLookupのエントリを見つけまして、AWSブログhttp://aws.typepad.com/aws_jp/2005/07/ruby_xml.htmlで紹介させていただきました。今後ともAWSをよろしくお願いいたします。何かお気づきの点などございましたら、いつでもご連絡ください。ありがとうございました。
投稿者 吉松史彰 : 2005年07月04日 11:26
A more simple-minded being there was a little reproachfully.
投稿者 weird quizzes : 2006年12月28日 11:40
Step by step did he- muttered Deerslayer; my young men ceased paddling, and collecting its cubs around her in childhood, an employment at which the prisoner had well be on the heart soon ceased to do with as much in gladness as with shame, and I am afraid, canoe after canoe bringing more and more of this, he grasped the arm, and joy, and he understood the necessity of returning at the door for the girl's companion been more alive to the observation of his dodging, and to wait for the Feeble Mind, she appeared resolute to draw any other.
投稿者 confidentiality and flu vaccinations : 2007年02月06日 11:42
I will send him back in the forest, like a man who had lately come from England, and so all must be terrible to think of naming your honest face and person that the young couple keep apart.
投稿者 dallas airport limouine service : 2007年02月06日 11:47