XPath的。如何选择所有文本节点,但只选择了选项'选项'在'选择'元件

时间:2014-07-15 13:36:21

标签: javascript xpath

我需要获取所有文本节点。

但当select元素在页面上时(包含一些选项元素)。只有一个option元素可见,应跳过其他元素。

HTML(只是一个例子):

<body onload="console.log(aaa());">
    <p>
        <span>hello</span>
        <span>world</span>
        <select>
            <option>one</option>
            <option>two</option>
            <option selected>three</option>
        </select>
    </p>
</body>

我使用以下javascript代码来使用我的xpath:

function aaa() {
    XPathResult.of = function(selector) {
        return document.evaluate(selector, document, null, XPathResult.ANY_TYPE, null);
    };

    XPathResult.prototype.toArray = function() {
        var nodes = [];
        var node = null;
        while ( (node = this.iterateNext()) ) {
            nodes.push(node);
        }
        return nodes;
    };

    return XPathResult.of("//body//text() | descendant::option[@selected]")
        .toArray()
        .map(function(node) {
            if ( node.nodeName == 'OPTION' ) { return node.value; }
            if ( node.nodeName == '#text' ) { return node.data.trim(); }
            throw new Error("unknown node type: " + node);
        })
        .filter(function(text) { return text.length; })

}

结果是:

[“你好”,“世界”,“一个”,“两个”,“三个”,“三个”]

但应该是

[“你好”,“世界”,“三”]

请帮助完成所需的xpath

2 个答案:

答案 0 :(得分:2)

使用XPath union(|)来组合XPath的结果,以获取不在<option>标记内并且不是空文本节点的所有文本节点:

//body//text()[not(parent::option) and normalize-space(.)]

...使用XPath获取所选<option>个节点中的所有文本节点:

//body//text()[parent::option[@selected]]

组合XPath:

//body//text()[parent::option[@selected]] | //body//text()[not(parent::option) and normalize-space(.)]

根据此问题给出HTML输入,上述XPath的输出将为["hello", "world", "three"]

答案 1 :(得分:1)

//body//text()将返回文档中的每个文本节点。 //body//text() | descendant::option[@selected]将返回文档中每个文本节点的并集,当前元素的每个<option selected>后代 - 仍然是文档中的每个文本节点。

如果您希望文档中除 <option>元素之外的每个单个文本节点没有@selected属性,您可以执行以下操作来过滤掉您不应该使用的元素我想:

//body//text()[not(parent::option[not(@selected)])]