如果我有两个XPath查询,其中第二个用于进一步深入查看第一个结果,我可以安全地让我的脚本将它们组合成单个查询...
引发此问题的具体用例涉及在幕后使用XPath根据外部提供的“CSS selector + attribute name”对从XML / XHTML文档中提取信息。
例如,脚本可能会输入以下内容:
选择器: a#home, a.chapter
属性: href
然后使用HTML::Selector::XPath Perl模块将选择器编译为XPath查询,并通过简单地为@
添加前缀... ...在这种情况下会产生:
XPath查询1: //a[@id='home'] | //a[contains(concat(' ', @class, ' '), ' chapter ')]
XPath查询2: @href
然后它反复将这些查询传递给libxml2的XPath引擎,从相关的XML文档中提取所请求的信息(在本例中为URL列表)。
它有效,但我更愿意将两个查询合并为一个,这将简化调用它们的代码并降低性能开销:
XPath查询: (//a[@id='home'] | //a[contains(concat(' ', @class, ' '), ' chapter ')])/@href
(注意添加的括号和斜线)
但对于任意输入查询,以编程方式安全吗?
答案 0 :(得分:2)
通常,不,您不能以这种方式连接两个任意XPath表达式,尤其是在XPath 1.0中。很容易找到反例:在XPath 1.0中你甚至不能在' /'的RHS上有一个联合表达式,所以连接" / a&#34 ;和"(b | c)"会失败。
在XPath 2.0中,结果总是在语法上有效,但是可能包含类型错误,例如:如果表达式是" count(a)"和" b"。 " /"的LHS操作数必须评估一系列节点。
答案 1 :(得分:1)
当然,这应该有效。但是,您始终必须尊重正确的上下文。如果第一个查询中示例中的元素没有href
属性,则会得到一个空结果集。
另外,你必须照顾例如在第二个查询前面的一个前导斜杠,这样你就不会有一个后代或自我轴的步骤,这可能不是你想要的。除此之外,这应该始终有效 - 可能发生的最糟糕的事情是它不合逻辑(即你没有得到预期的结果),但它应该始终是有效的XPath。