Modules and Prologs

これの実装ないですかって社内MLに投げたら、「SAXONで行けるかも」(QuiPってのでもいけるらしい。google:QuiP XQuery)って教えてもらって、ぐぐったらMozFxの拡張が出てきた。

試す。

productList.xml

<productList>
  <product no="1"/>
  <product no="11" parent="1"/>
  <product no="111" parent="11"/>
  <product no="112" parent="11"/>
  <product no="12" parent="1"/>
  <product no="2"/>
  <product no="21" parent="2"/>
  <product no="22" parent="2"/>
  <product no="23" parent="2"/>
</productList>

XQuery

declare variable $product_seq := fn:doc("file:///C:/productList.xml")/productList/product;

declare function local:layered($product) {
  element { fn:name($product) } {
    $product/@no,
    for $child in $product_seq[@parent=$product/@no]
    return local:layered($child)
  }
};

<result> {
  for $product in $product_seq[not(@parent)]
  return local:layered($product)
} </result>

ちなみに、ファイルではなく、[XML to query]フィールドにXMLを入力してもいい。その場合、fn:doc()のように空ドキュメントをクエリー式に書く。

result

<result>
  <product no="1">
    <product no="11">
      <product no="111"/>
      <product no="112"/>
    </product>
    <product no="12"/>
  </product>
  <product no="2">
    <product no="21"/>
    <product no="22"/>
    <product no="23"/>
  </product>
</result>

使える。導入の手軽さがいい。

……と、ここで同じクエリーをeXistにも投げたら通った。最初はダメだったのにい……。何かtypoしてたんだろうか。ちゃんとエラーメッセージ読まないとダメだな。