如何构造XPath以包含HTML中的特定元素?

时间:2019-01-29 20:47:08

标签: angular selenium xpath webdriverwait xpath-1.0

我有一张桌子,我只想选择该桌子上的按钮。我们可以看到,此表上只有4个按钮:

enter image description here

我创建了以下 Xpath ,以过滤出这些 4个按钮 ,并且页面:

//*[@id="studentListTable"]/thead/tr/th[contains(., "Actions")]//following::button  | //*[@id="studentListTable_info"]//preceding::button 
  • @ id =“ studentListTable_info”指的是文本“显示3个条目中的1到3”。

但这不起作用。
该XPath实际上是在页面上定位所有按钮,而与按钮的位置无关。

这是怎么了?

如何解决此问题,以便该表达式仅定位四个按钮?

HTML代码段:

<div _ngcontent-c7="" appcard="" class="card">
    <div _ngcontent-c7="" class="card-header">
        <h5 _ngcontent-c7="">Student list <!----></h5></div>
    <ul _ngcontent-c7="" class="card-actions">
        <li _ngcontent-c7="">
            <button _ngcontent-c7="" appcardfullscreen="" class="card-action">
                <i _ngcontent-c7="" class="fa fa-arrows-alt"></i></button></li>
        <li _ngcontent-c7="">
            <button _ngcontent-c7="" appcardcollapse="" class="card-action icon-collapse"><i _ngcontent-c7="" class="material-icons">expand_more</i></button></li></ul>
    <!---->
    <div _ngcontent-c7="" class="card-body">
        <div id="studentListTable_wrapper" class="dataTables_wrapper no-footer">
            <div class="dataTables_length" id="studentListTable_length">
                <label>Show <select name="studentListTable_length" aria-controls="studentListTable" class="">
                    <option value="10">10</option>
                    <option value="25">25</option>
                    <option value="50">50</option><option value="100">100</option>
                </select> entries</label></div>
            <div id="studentListTable_filter" class="dataTables_filter">
                <label>Search:<input type="search" class="" placeholder="" aria-controls="studentListTable"></label>
            </div>
            <table _ngcontent-c7="" class="table table-striped dataTable no-footer" datatable="" id="studentListTable" role="grid" aria-describedby="studentListTable_info">
            <thead _ngcontent-c7="">
            <tr _ngcontent-c7="" role="row">
                <th _ngcontent-c7="" class="sorting_asc" tabindex="0" aria-controls="studentListTable" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Student ID: activate to sort column descending" style="width: 101px;">Student ID</th>
                 <th _ngcontent-c7="" class="sorting_disabled" rowspan="1" colspan="1" aria-label="Actions" style="width: 106px;">Actions</th></tr>
            </thead><!----><tbody _ngcontent-c7=""><!---->
            <tr _ngcontent-c7="" role="row" class="odd">
                <td _ngcontent-c7="" class="sorting_1">123456</td>
                 <td _ngcontent-c7="">
                    <a href="unsafe:javascript:void(0)">
                        <i class="material-icons text-warning">info</i> Not Started</a></td>
                <td _ngcontent-c7="">Null</td>
                <td _ngcontent-c7="" class="text-left"><!----><div _ngcontent-c7="">
                    <button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-info" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button" tabindex="0">
                        <i _ngcontent-c7="" class="fa fa-arrow-right"></i></button></div><!----><!----><!----></td></tr>
            <tr _ngcontent-c7="" role="row" class="even">
                <td _ngcontent-c7="" class="sorting_1">153246</td>
                 <td _ngcontent-c7=""><a href="unsafe:javascript:void(0)"><i class="fa fa-unlock mr-2"></i>In Progress</a></td>
                <td _ngcontent-c7="">Herndon MS</td>
                <td _ngcontent-c7="" class="text-left"><!----><!----><div _ngcontent-c7=""><!----><div _ngcontent-c7="" class="d-flex align-items-center">
                    <button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-info col" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button" tabindex="0">
                        <i _ngcontent-c7="" class="fa fa-pencil"></i></button>
                    <button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-danger col" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button">
                        <i _ngcontent-c7="" class="fa fa-trash-o"></i></button></div><!----></div><!----><!----></td></tr>
            <tr _ngcontent-c7="" role="row" class="odd">
                <td _ngcontent-c7="" class="sorting_1">234135</td>
                 <td _ngcontent-c7="" class="text-left"><!----><!----><!---->
                    <div _ngcontent-c7="">
                        <button _ngcontent-c7="" class="btn btn-sm btn-sm-action mr-2 btn-outline-info" container="body" placement="left" popoverclass="btn-popover" triggers="mouseenter:mouseleave" type="button" tabindex="0">
                            <i _ngcontent-c7="" class="fa fa-eye"></i></button></div><!----></td></tr></tbody><!----><!----><!----></table>
            <div class="dataTables_info" id="studentListTable_info" role="status" aria-live="polite">Showing 1 to 3 of 3 entries</div>
            <div class="dataTables_paginate paging_simple_numbers" id="studentListTable_paginate">
                <a class="paginate_button previous disabled" aria-controls="studentListTable" data-dt-idx="0" tabindex="0" id="studentListTable_previous">Previous</a>
                <span>
                    <a class="paginate_button current" aria-controls="studentListTable" data-dt-idx="1" tabindex="0">1</a>
                </span>
                <a class="paginate_button next disabled" aria-controls="studentListTable" data-dt-idx="2" tabindex="0" id="studentListTable_next">Next</a></div></div></div></div>

6 个答案:

答案 0 :(得分:2)

  1. 第一个问题很难回答。
    您正在使用一些|和两个不同的id,但这可能并不完全正确。
    然后,您在Xpath中使用了thead元素。尽管所有按钮都位于tbody。 无论如何,您的定位器将从该页面获取所有HTML按钮。

  2. 我尝试将Xpath修改为以下内容:

  

//表//按钮

效果很好:

enter image description here

但是,它不是很好 Xpath
因此,尝试将其绑定到最近的id。更新后,它可能像:

  

// div [@ id ='studentListTable_wrapper'] //表//按钮

评估结果相同。

将会有更多的冗余版本(不推荐使用,仅出于示例原因):

  

// div [@ id ='studentListTable_wrapper'] // table / tbody / tr / td / div // button

顺便说一句,我认为更好的是使用定位器,例如:

  

// div [@id ='...']

代替:

  

// * [...]

很难查看是否可能是选择错误的原因。 当然,在以后的支持中, 可读 更容易理解

答案 1 :(得分:2)

您可以使用以下XPath-1.0表达式:

//table[@id="studentListTable" and thead/tr/th/text() =  "Actions"]/tbody/tr/td[@class="sorting_1"]

选择以下三个项目:

<td _ngcontent-c7="" class="sorting_1">123456</td>
<td _ngcontent-c7="" class="sorting_1">153246</td>
<td _ngcontent-c7="" class="sorting_1">234135</td>

要进一步获得这三个button中包含的四个table,下面的XPath可以做到:

//table[@id="studentListTable" and thead/tr/th/text() =  "Actions"]/tbody/tr/td[@class="sorting_1"]/../../tr/td//button

其结果包括以下四个项目:

<button ... type="button" tabindex="0">
    <i _ngcontent-c7="" class="fa fa-arrow-right"/>
</button>
<button ... type="button" tabindex="0">
    <i _ngcontent-c7="" class="fa fa-pencil"/>
</button>
<button ... type="button">
    <i _ngcontent-c7="" class="fa fa-trash-o"/>
</button>
<button ... type="button" tabindex="0">
    <i _ngcontent-c7="" class="fa fa-eye"/>
</button>

答案 2 :(得分:1)

几点:

  • 第一行和第三行中的按钮class="odd"
  • 之内
  • 第二行中的两个按钮class="even"
  • 之内

要过滤掉这4个按钮,可以使用以下基于 XPath 的解决方案:

"//table[@class='table table-striped dataTable no-footer' and @id='studentListTable']//tbody//tr[@class= 'odd' or @class='even']//td[@class='text-left']//button"

通过 xpath 检查器的匹配结果快照:

matching_xpath

注意:您没有提到您正在使用的语言绑定,因为这些元素是Angular元素,可以找到您要诱导的元素< em> WebDriverWait 来使元素可点击

答案 3 :(得分:0)

如果我正确理解这一点,那么标题就是您想要结合使用两个尝试过的XPath表达式来获取位于 th之后且包含文本“ Actions” 且在 {之前的按钮{1}},ID为“ studentListTable_info”

div

答案 4 :(得分:0)

您可以通过Student Id使用xpath下面的示例选择按钮,例如153246 id:

//table[@id='studentListTable']//tr[@role='row' and ./td[@class='sorting_1' and .='153246']]//button

答案 5 :(得分:-1)

您需要的BUTTON是表中的唯一按钮,并且该表具有ID studentListTable,因此您所需要的只是ID的子项BUTTON。 / p>

通过您提供的HTML,类似下面的简单内容将起作用。

XPath

//[@id='studentListTable']//button

CSS选择器

#studentListTable button