我正在编写一个相当基本的GreaseMonkey脚本,用于在特定元素中定位文本,然后使用该文本执行操作。代码的相关位如下:
在HTML中有一个带有“someclass”类的span,它包含一小段文本:
<span class="someclass">some text</span>
然后在JavaScript中我试图找到这个类并使用标准的XPath爵士将其内容('some text')拉入变量:
document.evaluate("//span[@class='someclass']/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
这就是问题:当我在“some text”是带有基本字符的基本字符串的页面上运行时,一切正常,但是当我在“some text”包含实体的页面上运行它时,它就会失败。例如,这些都很好,XPath返回我想要的文本:
<span class="someclass">some text</span>
<span class="someclass">some other text</span>
<span class="someclass">sometext</span>
<span class="someclass">some text 12345</span>
然而,这给了我一个错误:
<span class="someclass">some text's text</span>
返回的错误是:
Error: The expression is not a legal expression.
Source File: file:///blahblahblah.user.js
Line: (JS line i gave above)
我在这里和谷歌上发现了一些结果,谈论XPath如何解决实体问题,但他们都在做像[text() = 'blah &racquo; blah']
这样的事情 - 换句话说,他们的实体都在XPath查询中。我的不是,他们在文本中我试图从 XPath查询中返回。
这是同样的问题吗?有什么简单的方法吗?
谢谢!
答案 0 :(得分:1)
问题是 XPath表达式中的字符串文字必须用引号或撇号包围,并且不应包含周围的字符。
包含引号和撇号的文字字符串需要转换为(在您的情况下由您的Javascript程序)转换为不包含这两种字符的字符串。
执行此操作的最简单方法是将其中一种类型的字符的每个实例替换为其字符实体 - 例如将每个'
替换为'
并使用'
作为文字字符串的周围字符。
第二种方式是替换
some text's text
使用XPath表达式:
concat('some text', "'", ' text')
警告:使用不受信任的数据创建XPath表达式并不是一个好主意 - 这可能会导致 XPath injection 。为避免XPath注入,如果您的编程语言和函数库允许这样做,请始终编译您的 XPath表达式并将数据作为参数传递来运行它。