zerosp.blog > Web Programming > 2005/10/07 13:09 >

XPathを学ぼう

例えば資料.txtというファイルを作成してマイドキュメントに保存したとします。私たちから見ればマイドキュメントにある資料.txtです。しかしコンピューターからはD:\My Doc:\資料.txtといった感じでファイルを参照しています。DOS時代からパソコンを触っている人にはお馴染みなのですが、Pathというもので表します。

これに似たような感じでXML文章の各要素もXPathを使って要素を指定できます。その際に/ (スラッシュ)を用いて要素間の親子関係を繋げます。

ここで例題に上げるXML文章は、AWS3.0にてASIN Searchにて取得したミスチルのI LOVE U(ASIN:B000AOGRXU)のデータを一部抜粋して利用します。

Sample 01 : /AA/BB/CC

XPathの基本になります。文章のツリー構造を辿って要素の親子関係を"/"で繋げていって指定します。

<ProductInfo>
  <Details url="Associates URL">
    <Asin>B000AOGRXU</Asin>
    <ProductName>I LOVE U</ProductName>
    <Catalog>Music</Catalog>
  </Details>
</ProductInfo>

商品タイトルを表すProductName要素のXPathは/ProductInfo/Details/ProductNameになります。ProductName要素のテキストデータであるI LOVE Uを取得する場合は、/ProductInfo/Details/ProductName/text()になります。text()は省いて/ProductInfo/Details/ProductNameと書いてもOKです。自分で書いてみて分かりやすいほうにしてください。俺は書くのが面倒なのでいつもは省いています。あと忘れがちになりますが頭のRoot要素を表す"/"は忘れないで下さい。

さてProductInfo要素とDetails要素の関係は親子になります。Details要素とProductName要素も親子関係です。ではProductInfo要素とProductName要素の関係は何に当るでしょうか?ProductInfoからProductNameを見ると孫にあたり、ProductNameからProductInfoを見ると祖父にあたります。このように要素が先祖・子孫の関係にある場合は、今回の例でいうとこのようにも書くことができます。/ProductInfo//ProductNameになります。先祖・子孫の関係は//にて表すことができるわけです。極端なことを言うと更に短縮して、//ProductNameとも書けます。XMLツリーの一番親はRootに当りますからRootの子孫ということでこのようにも書けます。ただあんまり//を使うと見難くなる場合がありますので、そのあたりを見極めて使い分けるようにしましょう。

Sample02 : /AA/BB/@name

XML文章で要素を入れる場合は、<AA>Price</AA>となる場合が殆どだと思います。しかし中には、<AA name="Price" />と定義されている場合もあります。AWS3.0の場合ですと、商品のアフィリエイトリンクがそれにあたります。

<ProductInfo>
  <Details url="Associates URL">
    <Asin>B000AOGRXU</Asin>
    <ProductName>I LOVE U</ProductName>
    <Catalog>Music</Catalog>
  </Details>
</ProductInfo>

Associates URLのXPathは、/ProductInfo/Details/@urlになります。このurlのことをattribute要素といいます。attribute要素は@ (アットマーク)にて指定することになります。

Sample03 : /AA/BB[position() = 1]

このXPathは、同じ要素名がいくつかあってその中のn番目の値が欲しい場合に使います。

<ProductInfo>
  <Request>
    <Args>
      <Arg value="Mozilla/5.0" name="UserAgent"></Arg>
      <Arg value="0KS0TX5ZDYYS3YJTKN7T" name="RequestID"></Arg>
      <Arg value="B000AOGRXU" name="AsinSearch"></Arg>
      <Arg value="jp" name="locale"></Arg>
      <Arg value="Subscription ID" name="dev-t"></Arg>
      <Arg value="Associates ID" name="t"></Arg>
      <Arg value="xml" name="f"></Arg>
      <Arg value="heavy" name="type"></Arg>
    </Args>
  </Request>
</ProductInfo>

さてこれ例はいかがですか?Arg要素が8つあります。こうした場合で/ProductInfo/Request/Args/Arg/@valueと指定します。結果として返ってくる値は何になるでしょう?答えはMozilla/5.0です。同じ要素が複数あってXPathにて指定した場合は1番最初の要素が返ってきます。

では他の要素を指定するのはどうしたらいいでしょう。答えは/ProductInfo/Request/Args/Arg[position() = 3]/@valueになります。この場合はposition関数で3番目のものを指定しましたので、Arg要素の3番目のattribute要素のvalueの値であるB000AOGRXUが返されます。ちなみにArg[position() = 3]はArg[3]と略して書くこともできます。

position関数にはもう1つあります。それがlast関数です。lastという関数名が示すとおりに最後の要素を指定します。/ProductInfo/Request/Args/Arg[last()]/@valueと書くと取得できる値はheavyになります。

Sample04 : /AA/BB[@name = 'hoge']

先ほどのSample03の例ですと問題の起こる場合もあります。AWS3.0のArg要素はAWSにリクエストした時のパラメータ類が要素として収納されます。このパラメータの数などによってArg要素の順番が変わることもあります。ASIN番号を取得したくて/ProductInfo/Request/Args/Arg[position() = 3]/@valueとしてもASIN番号ではなくてSubscription IDが取得されてしまうかもしれません。今回の場合はArg要素のattribute要素に注目してください。uniqueな値であるname要素と内容によって変化するvalue要素になります。uniqueな値であるname要素(AsinSearch)をキーにして指定できればArg要素の順番に関係なくASIN番号を問題なく取得できます。

この場合のXPathは/ProductInfo/Request/Args/Arg[@name = 'AsinSearch']/@valueです。Arg[@name='xxx']とするとname要素が○○であるものの値というように指定できるようになります。

とりあえずAWS3.0でよく使いそうなのはこのくらいかな。これ以外のXPathは折をみてまた記事に書くと思います。

投稿日 2005-10-07 13:09

当サイトのコメントとトラックバックの扱いについて。

スパム対策のため認証制となっています。受け取ったコメント、トラックバックは一旦保留扱いとなり管理人が許可したものだけ表示されます。

トラックバック

  • XPathを学ぼうのトラックバックURL

コメント

コメントフォーム