2012-05-08 8 views
3

exslt拡張機能を使用してWebアプリケーションでjavascript XPathを使用したいと思いますが、これを行う方法がわかりません。exsltエクステンションをjavascript xpathsで使用する

私はそれにいくつかのdivを持つhtml文書を持っています。私はこれを実行したい:

namespaces={'regexp':'http://exslt.org/regular-expressions'}; 
result = document.evaluate( 
      "//div[regexp:test(.,'$')]", 
      document, 
      function(ns){ 
       return namespaces.hasOwnProperty(ns) ? namespaces[ns] : null; 
      }, 
      XPathResult.ANY_TYPE, 
      null); 

これは、評価では無効なXPath式例外が発生します。私はクロムを使用しています。

この作業を行うには他に何か必要なことはありますか?私はexslt.orgにjavascriptの実装があるのを見ていますが、どのようにそれらが利用可能であることを確認しますか? DOMの名前空間のスクリプト要素にJavaScriptを挿入する必要がありますか?

UPDATE

これは、直接(要素のリストを返すことがdocument.evaluateをシミュレートするために、ブラウザでEXSLT拡張を使用してXSLTを記述することは可能であろう、ブラウザのDOM + JavaScriptとXPathを使用できない場合はそれはxpathにマッチします)?

+0

SaxonCEの使用を検討しましたか?これはブラウザでXSLT 2.0を実行するためのサポートを提供しています(Chromeを含む主要5つのブラウザすべてで正常に動作します)。 –

+0

彼らはXSLT20Processorに相当するjavascript XPath20Evaluatorを公開していると素晴らしいでしょう。残念ながら、彼らはまだそのオプションを提供していません。しかし、チップのおかげで。それはそこにあることを知って良いです。 – underrun

+0

「それら」を待つ必要はありません。 SaxonCEのライセンスを取得して使用してください。 –

答えて

1

デフォルトのブラウザのXPath実装がEXSLTをサポートしているとは思われません。 EXSLTページに記載されているjavascriptのサポートは、in-browser.javascriptを使用してexslt関数を独自に実装する方法についての可能性があります。ここにはone example I was able to find very quicklyがあります。

例えば、Firefoxでは、Saxon-B as an extension to run XSLT2.0Saxon-B has built-in support for exslt (unlike Saxon-HE), though you will likely be better off just using XSLT/XPath 2.0 featuresを使用できます。たとえば、regular expression syntaxがあります。しかし、Mozilla Saxon-Bの拡張機能に頼っているのは、Chromeや他のブラウザの場合に役立つものではありません。

私は、XPathでEXSLT拡張機能を使用するためのクロスブラウザソリューションを見つけることはできないと思います。 DOM Level 3 XPathのconformance sectionにはXPath 1.0のサポートが必要であり、EXSLTについては言及していません。 INVALID_EXPRESSION_ERRがスローされると言われている:Firefoxは彼らのDOMレベル3 XPathの実装のEXSLTのサポートを開くため

if the expression has a syntax error or otherwise is not a legal expression according to the rules of the specific XPathEvaluator or contains specialized extension functions or variables not supported by this implementation.

は最後に、ここにopen bugzilla ticketです。それは2007年以来、新しい地位にそこに座っているようだ。チケットはそれを言う:

Currently Mozilla gives an exception "The expression is not a legal expression." even if a namespace resolver correctly resolving the EXSLT prefixes to the corresponding URLs is passed in。ここにはtest caseがあります。

-

あなたがのために正規表現を使用したいまさに、求めて私を気にしない場合は? standard XPath string functionsの組み合わせで手伝ってもらえるのでしょうか?

- (あなたがあなたの質問に更新して求めているように)あなたがXSLTを経由してXPathのランナーを構築することができますが、、それはソースドキュメントからノードを返しません

UPDATE、それは意志まったく同じように見える新しいノードを返します。 XSLTは新しい結果ツリードキュメントを生成し、元のノードへの参照を返す方法はないと思います。

Mozilla(とChrome)の両方で、外部ソースから読み込まれたXMLドキュメントだけでなく、表示されているドキュメントのDOMエレメントにも、support XSLTがあります。XSLTProcessor documentationには、tranformToFragment()の名前が記載されています。たとえば、will only produce HTML DOM objects if the owner document is itself an HTMLDocument, or if the output method of the stylesheet is HTMLです。

ここで私はあなたのIDEをテストする単純なXPathのランナーです:

1)まず、あなたがで動作するようにXSLTテンプレートが必要になります。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:regexp="http://exslt.org/regular-expressions" 
    extension-element-prefixes="regexp"> 

    <xsl:template match="/"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

私はdocument.implementation.createDocument APIを使ってJavaScriptでそれを構築し始めたが、ちょうどそれをロードするために容易になるだろう考え出しました。 FFはまだdocument.loadをサポートしていますが、ChromeではXHRを使って読み込むことしかできません。ローカルディスクからXHRでファイルをロードする場合は、--allow-file-access-from-filesでChromeを起動する必要があります。

2)私たちは、テンプレートをロードした後、我々は我々が必要とするXPathの実行にxsl:copy-of命令のselect属性の値を変更する必要があります:

function runXPath(xpath) { 
    var processor = new XSLTProcessor(); 
    var xsltns = 'http://www.w3.org/1999/XSL/Transform'; 

    var xmlhttp = new window.XMLHttpRequest(); 
    xmlhttp.open("GET", "xpathrunner.xslt", false); 
    xmlhttp.send(null); 

    var transform = xmlhttp.responseXML.documentElement; 

    var copyof = transform.getElementsByTagNameNS(xsltns, 'copy-of')[0]; 
    copyof.setAttribute('select', xpath); 

    processor.importStylesheet(transform);   

    var body = document.getElementById('body'); // I gave my <body> an id attribute 
    return processor.transformToFragment(body, document); 
} 

あなたは今のようなもので、それを実行することができました:

var nodes = runXPath('//div[@id]'); 
console.log(nodes.hasChildNodes()); 
if (nodes.firstChild) { 
    console.log(nodes.firstChild.localName); 
} 

それはその//div[@id](および//div[@not-there]を見つけることができない)のような「通常の」のXPath のための素晴らしい作品が、私はちょうどそれがregexp:testを実行するために取得することはできません拡張機能//div[regexp:test(string(@id), "a")]ではエラーは発生せず、ただ空のセットが返されます。

Mozillaのマニュアルにはtheir XSLT processor support EXSLTがあります。とにかく、彼らは舞台裏でlibxml/libxsltを使用していると思います。つまり、私はそれをMozillaでも動作させることができませんでした。

希望します。

jQuery regexpと一緒に逃げる可能性はありますか?あなたのXPathビルダー・ユーティリティーに役立つ可能性は低いですが、HTMLノードでregexpを実行する方法はまだありません。

+0

見通しは厳しいです。私はクロムをサポートしているだけでも見ています。特定の正規表現フィルタリングされたxpathを作成するのではなく、chrome拡張機能XPathヘルパー(https://chrome.google.com/webstore/detail/hgimnogjllphhhkhlmebbmlgjoejdpjlを参照)のようなhtml/css/javascriptでxpath作成者を作成することです。 。 – underrun

+0

はwiki /メーリングリストに尋ねるかもしれません。私はwikiとEXSLTの問題を検索し、これを見つけました:http://code.google.com/p/chromium/issues/detail?id=111655&q=EXSLT&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20Area%20Feature% 20Status%20Owner%20Summary。彼らはそこにEXSLTのためのいくつかのサポートを持っている必要がありますが、私はそれがDOMレベル3のXPathに公開されているかどうかはわかりません。 MozillaがDOM XPathでそれを持っていないことを知っていても、XSLTにそれがあるように見えますが、Chromeもそうではないと思います。 –

+0

@SynapticUnderrun XSLTベースのXPathランナーのアイデアを調べるためのアップデートを投稿しました。それは動作しますが、 'regexp:'拡張関数を実行する運はありません。 –

関連する問題