2011-07-19 6 views
5

ストックJAX-P xpath式エンジンまたは別の準拠エンジンで、パラメータ化を可能にするxpath式をコンパイルできますか?コンパイルされたJava XPath式ala PreparedStatementスタイルのセマンティクスをパラメータ化できますか?

開発者がコンパイル済みのxpath内でプレースホルダを設定し、実行時にこれらの値を置き換えることができるAPIがあるかどうかを調べたいと思っています。

これが可能かどうか、また注意点や落とし穴があるかどうか、またはっきりと「しないでください」というタイプのアドバイスは非常に高く評価されます。

(注:私は「ストリームの交差」を修正しました... xpathについての同僚との会話を持っていました&正規表現...ちょうど精神的に舌が結ばれました...混乱のために申し訳ありません)

+0

うわー!これについてのお返事ありがとうございます。これを指摘してくれた皆さんのおかげで、私はAPIを見過ごしてしまいました! –

答えて

4

「正規表現」があなたの質問にどこに収まるかはわかりません。

JAXP APIでは、XPath式に変数(たとえば//emp[ssn=$e])を含めることができ、変数の値は、APIの一部として提供するVariableResolverの呼び出しによって実行時に取得されます。 JAXP仕様は、どのような種類の値が受け入れられるかについてかなり緩やかであり、実装ごとに異なる可能性があります。

Saxon XPath API(s9api)ではこれをさらに使用して、式をコンパイルした時点で変数とその型を明示的に宣言し、式(XPath 2.0型)の変数に値を指定できます実行される。

+0

私はいくつかのコードサンプルを教えてくれますか? – everton

+0

@Michael - 混乱して申し訳ありません。さらに、答えを示す小さなコードサンプルやこれを示すページへのリンクを提供できますか?私はそれを確認するためにAPIを見に行くつもりです。 –

1

AFAIK、no。私はしばらく前にそれを研究し、String.format()を使用して終了しました。

しかし、この方法では、パラメータ化されたxpath exprとして一度コンパイルすることはできません。それがあなたが望むと思うものです。

+0

ええ、私がやっていたものは...まあまあ。 –

7

ここjavax.xml.xpath.XPathVariableResolver

import java.util.HashMap; 
import java.util.Map; 
import javax.xml.namespace.QName; 
import javax.xml.xpath.XPathVariableResolver; 

public class SimpleVariableResolver implements XPathVariableResolver { 

    private static final Map<QName, Object> vars = 
     new HashMap<QName, Object>(); 

    public void addVariable(QName name, Object value) { 
     vars.put(name, value); 
    } 

    public Object resolveVariable(QName name) { 
     return vars.get(name); 
    } 

} 

の非常に単純な実装はこのようにそれを使用します。このドキュメントでは

public static void main(String[] args) throws ParserConfigurationException, 
     SAXException, IOException, XPathExpressionException { 

    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder builder = domFactory.newDocumentBuilder(); 
    Document doc = builder.parse("workbook.xml"); 

    XPath xpath = XPathFactory.newInstance().newXPath(); 
    SimpleVariableResolver resolver = new SimpleVariableResolver(); 
    resolver.addVariable(new QName(null, "id"), 2); 
    xpath.setXPathVariableResolver(resolver); 
    XPathExpression expr = xpath.compile("/root/element[@id=$id]"); 
    Object result = expr.evaluate(doc, XPathConstants.NODESET); 

    NodeList nodes = (NodeList) result; 
    for (int i = 0; i < nodes.getLength(); i++) { 
     System.out.println(nodes.item(i).getTextContent()); 
    } 
} 

<root> 
    <element id="1">one</element> 
    <element id="2">two</element> 
    <element id="3">three</element> 
</root> 

が出力:

two 
+0

これもお送りいただきありがとうございます!私は、APIを読んだ後もこれをほぼ同じ方法で実装していました。 –

+0

私は@ everton-agnerの答えが好きで、それを投票しました。この答えは優れたコード例を示していますが、私は微妙な点が1) 'xpath.compile'は各変数置換のために' xpath.setXPathVariableResolver'の後に呼び出さなければならないと考えています。そして、2)XPathVariableResolverには、変わらない。ですからOPの質問には、これはSQLの 'PreparedStatement'型バインドと同じではないと思います。 – javabrett

関連する問題