是否可以过滤从XPath查询返回的后代元素?

时间:2013-03-06 14:04:30

标签: xpath yql yahoo-api

目前,我正在尝试使用以下查询从某些网站抓取表单:

select * from html 
where url="http://somedomain.com" 
and xpath="//form[@action]"

这会返回如下结果:

{
    form: {
        action: "/some/submit",
        id: "someId",
        div: {
            input: [
               ... some input elements here
            ]
        }
        fieldset: {
            div: {
                input: [
                    ... some more input elements here
                ]
            }
        }
    }
}

在某些网站上,这可能会达到很多级别,因此我不确定如何开始尝试过滤掉结果中不需要的元素。如果我可以在这里过滤它们,那么它将使我的后端代码更简单。基本上,我只是喜欢表单和任何标签,输入,选择(和选项)和textarea后代。

这是我尝试过的XPath查询,但我意识到元素层次结构不会被维护,如果页面上有多个表单,这可能会导致问题:

//form[@action]/descendant-or-self::*[self::form or self::input or self::select or self::textarea or self::label]

但是,我确实注意到此查询返回的元素不再在div和表单下的其他元素下返回。

2 个答案:

答案 0 :(得分:1)

我认为在您尝试的简单查询中不可能。

但是,创建一个包含一些JavaScript的新数据表并不是很多 。

数据表

一个快速的小<execute>块可能看起来像下面这样。

var elements = y.query("select * from html where url=@u and xpath=@x", {u: url, x: xpath}).results.elements();
var results = <url url={url}></url>;
for each (element in elements) {
    var result = element.copy();
    result.setChildren("");
    result.normalize();
    for each (descendant in y.xpath(element, filter)) {
        result.node += descendant;
    }
    results.node += result;
}
response.object = results;

»请参阅the full example data table

示例查询

use "store://VNZVLxovxTLeqYRH6yQQtc" as example;
select * from example where url="http://www.yahoo.com"

»请参阅this query in the YQL console

示例结果

Query results XML

希望上面是朝着正确方向迈出的一步,看起来并不太令人生畏。

<强>链接

答案 1 :(得分:0)

这是我过滤特定节点但仍然允许显示所有属性的父标记的方式:

//form[@name]/@* | //form[@action]/descendant-or-self::node()[name()='input' or name()='select' or name()='textarea' or name()='label']

如果页面上有多个表单标签,则应该通过此父标签对它们进行分组,而不是将它们全部绑定在一起并且无法识别。

如果它可以帮助您显示节点的方式,也可以反转联合:

//form[@action]/descendant-or-self::node()[name()='input' or name()='select' or name()='textarea' or name()='label'] | //form[@name]/@*