XPathを利用したXMLハンドリング

 

XMLのハンドリングについて、Curlでは、いくつかの方法が用意されています。
ここでは、WSDKというCurlの開発をサポートするキットで提供されている、
XPath表現を使ったハンドリングの例をご紹介します。

このエントリで紹介するアプリでは、顔ラボ から提供されている、画像の顔位置検出APIのXMLデータを利用しています。
顔ラボのサービスに画像のURLを渡すと、顔情報が保持されたXMLが返却されます。

 

■顔ラボ 返却XML例

<results version=”1.0″ xmlns=”http://xmlns.kaolabo.com/detect”>
   <faces>
     <face height=”60″ score=”742″ width=”60″ x=”234″ y=”117″>
        <left-eye x=”275″ y=”136″ />
        <right-eye x=”253″ y=”136″ />
     </face>
     <face height=”48″ score=”705″ width=”48″ x=”303″ y=”138″>
        <left-eye x=”336″ y=”153″ />
        <right-eye x=”318″ y=”153″ />
     </face>
     <face height=”36″ score=”505″ width=”36″ x=”134″ y=”143″>
        <left-eye x=”159″ y=”153″ />
        <right-eye x=”145″ y=”153″ />
     </face>
  </faces>
</results>

 results タグの中に、顔として認識されたブロックの位置情報が face タグとして格納されています。
各 face タグ の中には、属性として各顔位置情報が、
タグとして目の位置情報がそれぞれ格納されています。

顔ラボの詳細な仕様については、 http://kaolabo.com を見てください。

 

■顔マスクアプリ解説

顔マスクアプリ ([developers.curlap.com] に対する特権が必要です。)

アプリケーションダウンロード

上記WEBサービスを利用した顔マスクアプリケーションでは、
start.curl内の、下記コード部にて、返却されたXMLをXPathで解析しています。

|| XML構造をモデル化
let model:XDMElement = {build-xml preserve-whitespace? = false, strb}.root

・・・

|| 画像内の顔位置を示すXMLを解析する
{for i:int = 0 to ({model.search “//*[name()=’face’]”}.size) do

    let fr:ImageMask =
        {ImageMask
            {url “laughing-man-mini.gif”},
            height = ({model.search “//*[name()=’face’][” & i &”]/@height”}.as-int) * 1px,
            width = ({model.search “//*[name()=’face’][” & i &”]/@width”}.as-int) * 1px
        }
       
    {c.add
        fr,
        x = ({model.search “//*[name()=’face’][” & i &”]/@x”}.as-int) * 1px,
        y = ({model.search “//*[name()=’face’][” & i &”]/@y”}.as-int) * 1px + fr.height
    }
}

■{build-xml preserve-whitespace? = false, strb}

build-xml プロシージャを利用することで、対象のXMLをモデル化することが出来ます。
XDMDocument.root から XDMElementクラス型のXMLツリー全体を取得しています。

■{model.search “//*[name()=’face’]

{XDMElement.search XPath表現} では、XPath表現に合ったノードが、XDMNodeSetとして返却されます。
ここでは、XML内のタグで face という名前のタグをを取得しています。

さらに XDMNodeSetのサイズを、for文のカウントとして利用しています。

これによってXML内の顔情報の数だけループすることになります。

■{model.search “//*[name()=’face’][” & i &”]/@height”}

ループのカウントを表す変数 i を使って、順番に顔情報のタグを扱っています。
属性情報を取得するXPath表現である @ を利用して、height という属性の値を取得しています。

また、XDMNodeSet.as-int で、返却されたデータを int型で扱うようにしています。

 

XPathは、このプログラムで利用している表現以外にも、いろいろな書き方があります。
下記リソースなどを利用して、簡易なXMLハンドリングを試してみてください。

■XPath W3C 勧告
http://www.infoteria.com/jp/contents/xml-data/REC-xpath-19991116-jpn.htm

■XPath の概要
http://msugai.fc2web.com/java/XML/XPath.html