连接两个XPath 1.0查询是否安全?

时间:2014-05-02 23:06:47

标签: xpath

如果我有两个XPath查询,其中第二个用于进一步深入查看第一个结果,我可以安全地让我的脚本将它们组合成单个查询...

  1. 在第一个查询周围放置括号
  2. 使用斜杠为第二个查询添加前缀,然后
  3. 简单地连接两个字符串?
  4. 上下文

    引发此问题的具体用例涉及在幕后使用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

    (注意添加的括号和斜线)

    但对于任意输入查询,以编程方式安全吗?

2 个答案:

答案 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。