2009/12/12

Apache Velocityの困った挙動

VelocityでXPathを使うと、いろいろ困った事が起ります。 結局XPathを使うのは止めて、JDOMの範囲で処理をするようにしました。

テキストノードが引き出せないXPath

通常はタグの中にあるテキストは $node.selectNode("/element::text()") のような構文で取り出す事ができるのですが、Velocityの場合は text() の部分がエラーになります。 そのためテキストノードに到達するためには、 $node.getChild("element").getContent() のような形でアクセスする他に方法がありません。

この例だとそんなに問題がないように思えますが、特定の要素のアクセスする場合に差が出ます。 XPathの持つ /element[@attr='val'] の構文はループを使わずに特定の要素にアクセスができますが、Velocityの場合は #foreach を使い、 #if('val' == $item.getAttributeValue("attr")) のように条件にマッチする場合に処理を行なう必要があります。

結局要素全体にアクセスしたい場合に限定して使う事になるのですが、後述するように他にも問題があります。 XPathの構文を使わないようにするのも、少し冗長でも分かり易くみえていいのですが、期待してたので少し残念です。

日本語が使えないXPath

次に .selectNode("/chapter[@name='はじめに']") のように式の中に日本語を書くとエラーになります。 antlr-2.7.5.jarがバイト単位で処理しているのが原因なのかなぁ。日本語パッチがあるようなので最近のものには含まれているのかなと思い、jarファイルを最新の"antlr-3.2.jar"に差し替えてみましたが、同じエラーになりました。

最近はUTF-8に対応している字句解析器もありますが、日本語を通すのはやはり難しい場合が多いですね…。

対応自体はXPathを使わずに、JDOMの範囲で $node.getChild("chapter").getAttributeValue("name") == "はじめに" のようなコードを書けば問題なく動きます。 間違いなく意図した要素を指定するには、場合によって少し面倒ですが、丁寧に書きつつコメントで補うしかないかなぁ。

最後に

全体的にxpathはおまけの印象が強いでが、それでもVelocityは便利だと思います。 フレームワークは制限が多少きつめな方が集中できて良いのかもしれないですね。

0 件のコメント: