最近AppleWatchで収集した自分のヘルスケアデータをRailsで処理しはじめた
ヘルスケアデータはexport_cda.xmlと書き出す.xmlがある
今回はexport_cda.xmlから心拍数の一覧を取り出すのをゴールにする
Rubyでどう処理するか
個人的にもよく使っているnokogiriを使用することにした
普段は Nokogiri::HTML
でHTMLをパースすることが多いがxmlの時はNokogiri::XML
を使うことが出来る
Parsing
まずはexport_cda.xmlを読み込む
> doc = File.open('export_cda.xml') { |f| Nokogiri::XML(f) }
次にパスを指定して心拍数一覧を取得
> doc.xpath("/ClinicalDocument/entry/organizer/component/observation/text/type[text()='HKQuantityTypeIdentifierHeartRate']/../value").map(&:text).join(',') # => ""
がしかしとれない
xmlファイルを開いて見てみる
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 ../../../CDA%20R2/cda-schemas-and-samples/infrastructure/cda/CDA.xsd" xmlns="urn:hl7-org:v3" xmlns:cda="urn:hl7-org:v3" xmlns:sdtc="urn:l7-org:sdtc" xmlns:fhir="http://hl7.org/fhir/v3">
何やら色々かかれている
xmlは複数のマークアップ言語を扱うことが出来るが、それぞれの仕様が衝突しないように名前空間を設定することが出来る
その時使われるのがxmlns
で今回はNokogiri側でその名前空間が考慮されていなかった
さきほどのxpathを下記のように名前空間を指定することで取得ができるようになる
> doc.xpath("/ns:ClinicalDocument/ns:entry/ns:organizer/ns:component/ns:observation/ns:text/ns:type[text()='HKQuantityTypeIdentifierHeartRate']/../ns:value", {ns: "urn:hl7-org:v3"}).map(&:text).join(',') # => "41,81,81,88,83,81,89,74,77,74,83,81,76,74,78,72,70,79,74,69,74,74,74,74,74,69,69,75,80,87,74,74,71,84,86,81,74"
とれた!!
ただ毎回名前空間を指定するのは面倒な時はnokogiri側に名前空間を取り除くメソッドがはえており下記のようにしようすることが出来る
> doc.remove_namespaces! # xmlから名前空間を取り除く > doc.xpath("/ClinicalDocument/entry/organizer/component/observation/text/type[text()='HKQuantityTypeIdentifierHeartRate']/../value").map(&:text).join(',') # => "41,81,81,88,83,81,89,74,77,74,83,81,76,74,78,72,70,79,74,69,74,74,74,74,74,69,69,75,80,87,74,74,71,84,86,81,74"