我认为默认浏览器 XPath 实现不支持 EXSLT。EXSLT 页面上提到的 javascript 支持可能是关于如何使用 in-browser.javascript 提供自己的 exslt 函数实现。这是我能很快找到的一个例子。
例如,在 Firefox 中,您可以将Saxon-B 作为扩展来运行 XSLT2.0,并且Saxon-B 具有对 exslt 的内置支持(与 Saxon-HE 不同),尽管使用 XSLT/XPath 可能会更好2.0 功能。例如,这是正则表达式语法。尽管如此,依靠 Mozilla Saxon-B 扩展程序并不能帮助您使用 Chrome 或其他浏览器。
话虽如此,我认为您找不到在 XPath 中使用 EXSLT 扩展的跨浏览器解决方案。DOM Level 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.
最后,这是一个开放的 bugzilla 票证,供 Firefox 为他们的 DOM Level 3 XPath 实现开放 EXSLT 支持。自 2007 年以来,它似乎一直处于 NEW 状态。票据上写着:
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)都支持 XSLT,不仅支持从外部源加载的 XML 文档,还支持正在显示的文档中的 DOM 元素。该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 Runner,我构建了它来测试您的 ide:
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属性的值来运行我们需要的 XPath:xsl:copy-of
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 节点上运行正则表达式的一种方式。