3

exslt 拡張機能を使用して Web アプリで JavaScript XPath を使用したいのですが、これを行う方法がわかりません。

いくつかの 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 式の例外が発生します。私はクロムを使用しています。

これを機能させるために他に何かする必要がありますか? javascript の実装があることを exslt.org で確認しましたが、それらが利用可能であることを確認するにはどうすればよいですか? javascript を dom の名前空間付きスクリプト要素に挿入する必要がありますか?

アップデート

ブラウザの dom + javascript と xpath を直接使用してこれができない場合、ブラウザで exslt 拡張機能を使用して XSLT を記述し、document.evaluate (xpath に一致する要素のリストを返す) をシミュレートすることは可能でしょうか?

4

1 に答える 1

1

デフォルトのブラウザー XPath 実装が EXSLT をサポートしているとは思わない。EXSLT ページに記載されている JavaScript サポートは、in-browser.javascript を使用して exslt 関数の独自の実装を提供する方法に関するものと思われます。これは、私がすぐに見つけることができた 1 つの例です。

たとえば Firefox では、Saxon-B を拡張機能として XSLT2.0 を実行することができ、Saxon-B には exslt のサポートが組み込まれています (Saxon-HE とは異なります)。 2.0 の機能. たとえば、正規表現の構文は次のとおりです。とはいえ、Mozilla Saxon-B 拡張機能に依存することは、Chrome やその他のブラウザーで役立つものではありません。

そうは言っても、XPath で EXSLT 拡張機能を使用するためのクロスブラウザー ソリューションを見つけることはできないと思います。DOM レベル 3 XPathの適合セクションでは、XPath 1.0 のサポートが必要であり、EXSLT については言及されていません。はINVALID_EXPRESSION_ERR投げられると言われています:

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.

最後に、Firefox が DOM レベル 3 XPath 実装の EXSLT サポートを開くためのオープン Bugzillaチケットを次に示します。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. これがテストケースです。

--

よろしければ、正規表現を正確に何に使用したかったのですか? 標準の XPath 文字列関数を組み合わせることで解決できるのではないでしょうか?

--

更新XSLT を介して XPath ランナーを構築できますが (質問の更新で尋ねているように) 、ソース ドキュメントからノードを返さず、まったく同じに見える新しいノードを返します。XSLT は新しい結果ツリー ドキュメントを生成しますが、元のノードへの参照を返す方法はないと思います。

私が知る限り、Mozilla (および Chrome) は両方とも、外部ソースからロードされた XML ドキュメントだけでなく、表示されているドキュメントの DOM 要素に対してもXSLT をサポートしています。XSLTProcessorドキュメントには、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.

これは、あなたのアイデアをテストするために作成した単純な 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>

APIを使用して JavaScript でビルドを開始しdocument.implementation.createDocumentましたが、ロードするだけの方が簡単だと考えました。FF は引き続きサポートdocument.loadしていますが、Chrome では XHR を使用してのみロードできます。--allow-file-access-from-filesローカル ディスクから XHR を使用してファイルをロードする場合は、Chrome を起動する必要があります。

2) テンプレートをロードしたらselect、命令の属性の値を変更して、xsl:copy-of必要な XPath を実行する必要があります。

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);
}

そのような「通常の」XPathでは//div[@id]うまく機能します(そして、 を見つけることができません//div[@not-there])が、拡張機能を実行することはできませんregexp:test//div[regexp:test(string(@id), "a")]エラーが発生せず、空のセットを返すだけです。

Mozilla のドキュメントでは、XSLT プロセッサが EXSLT をサポートすることが提案されています。いずれにせよ、それらはすべて舞台裏で libxml/libxslt を使用していると思います。とはいえ、Mozilla でも動作させることができませんでした。

それが役に立てば幸い。

jQuery regexpを回避できる可能性はありますか? XPath ビルダー ユーティリティにはあまり役に立ちませんが、それでも HTML ノードで正規表現を実行する方法にはなります。

于 2012-05-14T18:00:21.967 に答える