2008年03月06日(木) [長年日記]
- NTTコミュニケーションズから葉書が来ていて、電話番号が変わったらNTTコミュニケーションズにも連絡してくれと書いてあった。でも理由が書かれていない。電話する必要はなさそうに思う。
■ [dev][web] XPathを使う
XPathを使う必要がある。XPathは過去に何度か勉強したがすぐに忘れてしまい身に付かない。身に付かないのはメモしないからなので、今回はメモする。
RubyのREXMLを使って次のスクリプトを書いた。
#!/usr/bin/ruby
require "rexml/document"
xml = <<EOF
<root>
<momo>
<buka>
<name>hideyoshi</name>
<type>saru</type>
<weapon>panchi</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
<momo>
<buka>
<name>taro</name>
<type>inu</type>
<weapon>kick</weapon>
</buka>
</momo>
<momo>
<buka>
<name>jiro</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
<momo>
<buka>
<name>unknown</name>
<type>kiji</type>
<weapon>tutuki</weapon>
<weapon>tutuki</weapon>
<weapon>tutuki</weapon>
<weapon>tutuki</weapon>
</buka>
</momo>
</root>
EOF
doc = REXML::Document.new(xml)
xpaths = [
["/root/momo/buka/type", "/root/momo/buka/type"],
["//buka", "buka全て"],
["//type", "type全て"],
["//type/text()", "typeの内容全て"],
["//type[text()='inu']", "内容がinuのtype全て"],
["//momo[buka/type/text()='inu']", "内容がinuのtypeを持つmomo全て"],
["//momo[buka[type/text()='inu']]", "これでもいいみたい"],
["//momo[buka[type/text()='inu'][count(weapon)>=4]]",
"内容がinuのtypeを持ち、weaponの数が4つ以上のmomo全て"],
["//momo[buka[type/text()='inu'][count(weapon[text()='kamituki'])>=3]]",
"内容がinuのtypeを持ち、内容がkamitukiのweaponの数が4つ以上のmomo全て"],
["//momo[buka[type/text()='inu' and count(weapon[text()='kamituki'])>=3]]",
"それともこう書くのかな"],
["//*[local-name()='momo']" +
"[*[" +
"[*[local-name()='type'][text()='inu']]" +
"[count(*[local-name()='weapon'][text()='kamituki'])>=3]" +
"]]",
"訳あってlocal-nameだけを使って頑張って書く。合っているかわからん。"],
]
xpaths.each {|x, text|
puts "-" * 40
puts text
puts "XPath: #{x}"
puts "-" * 40
puts REXML::XPath.match(doc, x)
puts
}
実行結果は次の通り。
----------------------------------------
/root/momo/buka/type
XPath: /root/momo/buka/type
----------------------------------------
<type>saru</type>
<type>inu</type>
<type>inu</type>
<type>inu</type>
<type>kiji</type>
----------------------------------------
buka全て
XPath: //buka
----------------------------------------
<buka>
<name>hideyoshi</name>
<type>saru</type>
<weapon>panchi</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
<buka>
<name>taro</name>
<type>inu</type>
<weapon>kick</weapon>
</buka>
<buka>
<name>jiro</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
<buka>
<name>unknown</name>
<type>kiji</type>
<weapon>tutuki</weapon>
<weapon>tutuki</weapon>
<weapon>tutuki</weapon>
<weapon>tutuki</weapon>
</buka>
----------------------------------------
type全て
XPath: //type
----------------------------------------
<type>saru</type>
<type>inu</type>
<type>inu</type>
<type>inu</type>
<type>kiji</type>
----------------------------------------
typeの内容全て
XPath: //type/text()
----------------------------------------
saru
inu
inu
inu
kiji
----------------------------------------
内容がinuのtype全て
XPath: //type[text()='inu']
----------------------------------------
<type>inu</type>
<type>inu</type>
<type>inu</type>
----------------------------------------
内容がinuのtypeを持つmomo全て
XPath: //momo[buka/type/text()='inu']
----------------------------------------
<momo>
<buka>
<name>taro</name>
<type>inu</type>
<weapon>kick</weapon>
</buka>
</momo>
<momo>
<buka>
<name>jiro</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
----------------------------------------
これでもいいみたい
XPath: //momo[buka[type/text()='inu']]
----------------------------------------
<momo>
<buka>
<name>taro</name>
<type>inu</type>
<weapon>kick</weapon>
</buka>
</momo>
<momo>
<buka>
<name>jiro</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
----------------------------------------
内容がinuのtypeを持ち、weaponの数が4つ以上のmomo全て
XPath: //momo[buka[type/text()='inu'][count(weapon)>=4]]
----------------------------------------
<momo>
<buka>
<name>jiro</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
----------------------------------------
内容がinuのtypeを持ち、内容がkamitukiのweaponの数が4つ以上のmomo全て
XPath: //momo[buka[type/text()='inu'][count(weapon[text()='kamituki'])>=3]]
----------------------------------------
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
----------------------------------------
それともこう書くのかな
XPath: //momo[buka[type/text()='inu' and count(weapon[text()='kamituki'])>=3]]
----------------------------------------
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
----------------------------------------
訳あってlocal-nameだけを使って頑張って書く。合っているかわからん。
XPath: //*[local-name()='momo'][*[[*[local-name()='type'][text()='inu']][count(*[local-name()='weapon'][text()='kamituki'])>=3]]]
----------------------------------------
<momo>
<buka>
<name>otosan</name>
<type>inu</type>
<weapon>kick</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
<weapon>kamituki</weapon>
</buka>
</momo>
本当は名前空間も使う必要があって、その場合はまだよくわかってない。REXMLは名前空間をきちんと扱えないらしいしな。
参考
■ やること
- クレジットカード
- 新税務署
- ダンボール
[ツッコミを入れる]