【问题标题】:Why does normalize-space(text()) not work with a preceding child element?为什么 normalize-space(text()) 不适用于前面的子元素?
【发布时间】:2019-04-15 13:56:08
【问题描述】:

毫无疑问,这是非常基本的,但它对我来说不会“点击”,尽管到目前为止我已经进行了研究。给定以下两个 HTML 示例:

示例 1

<div _ngcontent-c35="" class="row facet-container ng-star-inserted">
    <div _ngcontent-c35="" class="searchresult-header">
        Locatie
    </div>
</div>

示例 2

<div _ngcontent-c42="" class="row facet-panel ng-star-inserted">
    <div _ngcontent-c42="" class="facet-panel-header brand-pointer" data-target="#ft5" data-toggle="collapse">
        <span _ngcontent-c42="" class="icon-plus ng-star-inserted" data-target="#ft5" data-toggle="collapse">
        </span> 
        Locatie
    </div>
    <div _ngcontent-c42="" class="collapse" id="ft5">
    </div>
</div>

现在我有了以下 xpath:

//div[.//div[normalize-space(text())='Locatie']]

根据其他questions 和有关xpath 的网站,text() 选择直接从我们正在搜索的节点下降的文本节点。因此,在示例 #1 中,我希望检索第一个子“div”元素。这是正确的:没有问题。

我希望示例 #2 中的结果相同。然而,情况并非如此:显然“span”元素破坏了这个特定的搜索。当我手动删除它时,我成功检索了所需的“div”元素。为什么搜索会中断?文本仍然应该是 div 元素的直接子元素,无论 span 元素是否存在。

TLDR:为什么“span”元素会阻止我在示例 #2 中找到第二个“div”元素?

【问题讨论】:

    标签: html xpath


    【解决方案1】:

    作为Jason had answered,这是因为normalize-space()函数的签名,来自规范:

    函数:字符串 规范化空间(字符串?)

    在 XPath 1.0 中,只要需要字符串参数,该语言就会通过 string() 函数应用类型转换。从规格:

    通过返回的字符串值将节点集转换为字符串 节点集中按文档顺序排在第一位的节点。如果 节点集为空,返回一个空字符串。

    因此,text() 节点测试的结果节点集被简化为文档顺序中的第一个节点,然后该节点被转换为其string-value。

    在这方面,当总是监督空白时,只有文本节点才会注意到:您的 div 元素有两个文本节点:

    <div>
        <div>
            <!-- HERE ENDS THE FIRST --><span>
            </span> 
            Locatie
        <!-- HERE ENDS THE SECOND --></div>
        <div>
        </div>
    </div>
    

    当你有混合内容标记时,最好使用字符串值而不是文本节点。否则你应该使用这个表达式:

    //div[.//div/text()[normalize-space()='Locatie']]
    

    【讨论】:

    • 加 1 用于提及混合内容。
    【解决方案2】:

    我猜这是因为normalize-space(text())='Locatie'] 打算检查 first 子文本节点(实际上只是一个空字符串),而您需要检查 second 一个:

    //div[.//div[normalize-space(text()[2])='Locatie']]
    

    如果您需要适用于这两种情况的通用 XPath,请尝试

    //div[normalize-space(div)='Locatie']
    

    【讨论】:

      【解决方案3】:

      这可能与白色文本/空格有关(这超出了我的工资等级...),因为随着焦点的变化,以下表达式似乎适用于大多数(不是全部)xpath 测试人员:

      .//div[text()[contains(.,'Locat')]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        • 2014-02-02
        • 2017-05-05
        • 2016-02-15
        • 1970-01-01
        • 2020-05-17
        • 1970-01-01
        相关资源
        最近更新 更多