基于其标签的输入的 xpath

xpath for input based of its label

我想select一个输入,基于它的标签。我在 xpath 下面找到了 returns 3 个输入,即使 returned 输入中的两个具有不同的标签。我想了解为什么它会这样工作以及如何将其改进为 return 正确的(一个)输入元素。这是 xpath:

//input[@id=(//label[.='Max Driving Time_h']/@for)]

是的,我知道我可以像这样使用 xpath 获得正确的输入:

//label[.='Max Driving Time_h']/ancestor::div/input

我只是想了解一下,第一个 xpath 有什么问题 ;) 先谢谢你了!

这是要尝试的 HTML 代码...

<!DOCTYPE html>
<html>
   <head>
      <title>Page Title</title>
   </head>
   <body>
      <div class="mat-tab-body-wrapper">
         <mat-tab-body role="tabpanel" class="mat-tab-body ng-tns-c344-232 mat-tab-body-active ng-star-inserted" id="mat-tab-content-4-0" aria-labelledby="mat-tab-label-4-0">
            <div cdkscrollable="" class="mat-tab-body-content ng-tns-c344-232 ng-trigger ng-trigger-translateTab" style="transform: none;">
               <!---->
               <div fxlayout="column" fxlayoutalign="space-between start" style="padding-top: 10px; flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start space-between; align-items: flex-start;" class="ng-star-inserted">
                  <dsg-input-duration class="ng-valid ng-touched ng-dirty">
                     <div flex-wrap="nowrap" style="display: inline-block; margin-right: 15px;" class="ng-valid ng-untouched ng-pristine">
                        <div fxlayout="column" fxlayoutalign="start start" class="mainLayout" style="flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start; align-items: flex-start;">
                           <div class="placeHolder">Max Driving Time</div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <mat-form-field floatlabel="always" class="mat-form-field durationField durationLabel ng-tns-c84-225 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-225">
                                    <div class="mat-form-field-flex ng-tns-c84-225">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-225">
                                          <input matinput="" formcontrolname="hours" id="h" name="h" type="number" min="0" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-225 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false" max="23">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-225">
                                             <label class="mat-form-field-label ng-tns-c84-225 ng-star-inserted" id="mat-form-field-label-179" for="h" aria-owns="h">
                                                <!---->
                                                <mat-label style="visibility: hidden !important;" class="ng-tns-c84-225 ng-star-inserted">Max Driving Time_h</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-225 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-225"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-225">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-225 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-225"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="h" class="durationSpaceForInputs">h</label>
                              <mat-form-field class="mat-form-field durationField durationLabel ng-tns-c84-226 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-has-label ng-valid ng-star-inserted mat-form-field-should-float ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-226">
                                    <div class="mat-form-field-flex ng-tns-c84-226">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-226">
                                          <input matinput="" formcontrolname="minutes" id="m" name="m" type="number" min="0" max="59" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-226 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-226">
                                             <label class="mat-form-field-label ng-tns-c84-226 ng-star-inserted" id="mat-form-field-label-181" for="m" aria-owns="m">
                                                <!---->
                                                <mat-label style="visibility: hidden !important; display: none;" class="ng-tns-c84-226 ng-star-inserted">Max Driving Time_m</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-226 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-226"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-226">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-226 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-226"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="m" class="durationSpaceForInputs">m</label><!----><!---->
                           </div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <div fxlayout="column" class="errorMessage" style="flex-direction: column; box-sizing: border-box; display: flex;">
                                 <!----><!----><!----><!----><!----><!----><!----><!----><!---->
                              </div>
                           </div>
                        </div>
                     </div>
                  </dsg-input-duration>
                  <dsg-input-duration class="ng-valid ng-touched ng-dirty">
                     <div flex-wrap="nowrap" style="display: inline-block; margin-right: 15px;" class="ng-valid ng-untouched ng-pristine">
                        <div fxlayout="column" fxlayoutalign="start start" class="mainLayout" style="flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start; align-items: flex-start;">
                           <div class="placeHolder">Max Elapsed Time</div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <mat-form-field floatlabel="always" class="mat-form-field durationField durationLabel ng-tns-c84-227 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-227">
                                    <div class="mat-form-field-flex ng-tns-c84-227">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-227">
                                          <input matinput="" formcontrolname="hours" id="h" name="h" type="number" min="0" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-227 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false" max="23">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-227">
                                             <label class="mat-form-field-label ng-tns-c84-227 ng-star-inserted" id="mat-form-field-label-183" for="h" aria-owns="h">
                                                <!---->
                                                <mat-label style="visibility: hidden !important;" class="ng-tns-c84-227 ng-star-inserted">Max Elapsed Time_h</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-227 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-227"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-227">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-227 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-227"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="h" class="durationSpaceForInputs">h</label>
                              <mat-form-field class="mat-form-field durationField durationLabel ng-tns-c84-228 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-has-label ng-valid ng-star-inserted mat-form-field-should-float ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-228">
                                    <div class="mat-form-field-flex ng-tns-c84-228">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-228">
                                          <input matinput="" formcontrolname="minutes" id="m" name="m" type="number" min="0" max="59" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-228 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-228">
                                             <label class="mat-form-field-label ng-tns-c84-228 ng-star-inserted" id="mat-form-field-label-185" for="m" aria-owns="m">
                                                <!---->
                                                <mat-label style="visibility: hidden !important; display: none;" class="ng-tns-c84-228 ng-star-inserted">Max Elapsed Time_m</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-228 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-228"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-228">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-228 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-228"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="m" class="durationSpaceForInputs">m</label><!----><!---->
                           </div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <div fxlayout="column" class="errorMessage" style="flex-direction: column; box-sizing: border-box; display: flex;">
                                 <!----><!----><!----><!----><!----><!----><!----><!----><!---->
                              </div>
                           </div>
                        </div>
                     </div>
                  </dsg-input-duration>
                  <dsg-input-duration class="ng-valid ng-touched ng-dirty">
                     <div flex-wrap="nowrap" style="display: inline-block; margin-right: 15px;" class="ng-valid ng-untouched ng-pristine">
                        <div fxlayout="column" fxlayoutalign="start start" class="mainLayout" style="flex-direction: column; box-sizing: border-box; display: flex; place-content: flex-start; align-items: flex-start;">
                           <div class="placeHolder">Max Working Time</div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <mat-form-field floatlabel="always" class="mat-form-field durationField durationLabel ng-tns-c84-229 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-229">
                                    <div class="mat-form-field-flex ng-tns-c84-229">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-229">
                                          <input matinput="" formcontrolname="hours" id="h" name="h" type="number" min="0" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-229 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false" max="23">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-229">
                                             <label class="mat-form-field-label ng-tns-c84-229 ng-star-inserted" id="mat-form-field-label-187" for="h" aria-owns="h">
                                                <!---->
                                                <mat-label style="visibility: hidden !important;" class="ng-tns-c84-229 ng-star-inserted">Max Working Time_h</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-229 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-229"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-229">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-229 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-229"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="h" class="durationSpaceForInputs">h</label>
                              <mat-form-field class="mat-form-field durationField durationLabel ng-tns-c84-230 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-has-label ng-valid ng-star-inserted mat-form-field-should-float ng-untouched ng-pristine">
                                 <div class="mat-form-field-wrapper ng-tns-c84-230">
                                    <div class="mat-form-field-flex ng-tns-c84-230">
                                       <!----><!---->
                                       <div class="mat-form-field-infix ng-tns-c84-230">
                                          <input matinput="" formcontrolname="minutes" id="m" name="m" type="number" min="0" max="59" autocomplete="really-off" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-230 ng-valid cdk-text-field-autofill-monitored ng-untouched ng-pristine" aria-invalid="false" aria-required="false">
                                          <span class="mat-form-field-label-wrapper ng-tns-c84-230">
                                             <label class="mat-form-field-label ng-tns-c84-230 ng-star-inserted" id="mat-form-field-label-189" for="m" aria-owns="m">
                                                <!---->
                                                <mat-label style="visibility: hidden !important; display: none;" class="ng-tns-c84-230 ng-star-inserted">Max Working Time_m</mat-label>
                                                <!----><!---->
                                             </label>
                                             <!---->
                                          </span>
                                       </div>
                                       <!---->
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c84-230 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-230"></span></div>
                                    <!---->
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c84-230">
                                       <!---->
                                       <div class="mat-form-field-hint-wrapper ng-tns-c84-230 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                          <!---->
                                          <div class="mat-form-field-hint-spacer ng-tns-c84-230"></div>
                                       </div>
                                       <!---->
                                    </div>
                                 </div>
                              </mat-form-field>
                              <label for="m" class="durationSpaceForInputs">m</label><!----><!---->
                           </div>
                           <div fxlayout="row" style="flex-direction: row; box-sizing: border-box; display: flex;">
                              <div fxlayout="column" class="errorMessage" style="flex-direction: column; box-sizing: border-box; display: flex;">
                                 <!----><!----><!----><!----><!----><!----><!----><!----><!---->
                              </div>
                           </div>
                        </div>
                     </div>
                  </dsg-input-duration>
                  <dsg-input-number controlname="maxDistance">
                     <div class="ng-touched ng-dirty ng-valid" style="display: inline-block;">
                        <mat-form-field floatlabel="always" class="mat-form-field ng-tns-c84-231 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-legacy mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label ng-valid ng-star-inserted ng-touched ng-pristine">
                           <div class="mat-form-field-wrapper ng-tns-c84-231">
                              <div class="mat-form-field-flex ng-tns-c84-231">
                                 <!----><!---->
                                 <div class="mat-form-field-infix ng-tns-c84-231">
                                    <input matinput="" type="number" class="mat-input-element mat-form-field-autofill-control ng-tns-c84-231 ng-valid cdk-text-field-autofill-monitored ng-touched ng-pristine" autofocus="" autocomplete="off" step="" id="maxDistance" data-placeholder="" aria-invalid="false" aria-required="false" min="-Infinity" max="2147483647" maxlength="14">
                                    <span class="mat-form-field-label-wrapper ng-tns-c84-231">
                                       <label class="mat-form-field-label ng-tns-c84-231 ng-star-inserted" id="mat-form-field-label-191" for="maxDistance" aria-owns="maxDistance">
                                          <!---->
                                          <mat-label class="ng-tns-c84-231 ng-star-inserted">Max Distance [km]</mat-label>
                                          <!----><!---->
                                       </label>
                                       <!---->
                                    </span>
                                 </div>
                                 <!---->
                              </div>
                              <div class="mat-form-field-underline ng-tns-c84-231 ng-star-inserted"><span class="mat-form-field-ripple ng-tns-c84-231"></span></div>
                              <!---->
                              <div class="mat-form-field-subscript-wrapper ng-tns-c84-231">
                                 <!---->
                                 <div class="mat-form-field-hint-wrapper ng-tns-c84-231 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                    <!---->
                                    <div class="mat-form-field-hint-spacer ng-tns-c84-231"></div>
                                 </div>
                                 <!---->
                              </div>
                           </div>
                        </mat-form-field>
                     </div>
                  </dsg-input-number>
               </div>
               <!---->
            </div>
         </mat-tab-body>
         <mat-tab-body role="tabpanel" class="mat-tab-body ng-tns-c344-233 ng-star-inserted" id="mat-tab-content-4-1" aria-labelledby="mat-tab-label-4-1">
            <div cdkscrollable="" class="mat-tab-body-content ng-tns-c344-233 ng-trigger ng-trigger-translateTab" style="transform: translate3d(100%, 0px, 0px); min-height: 1px;">
               <!---->
            </div>
         </mat-tab-body>
         <!---->
      </div>
   </body>
</html>

尝试以下 XPath:

//input[@id=(./following::label[.='Max Driving Time_h']/@for)]

您的 XPath 不起作用,因为它声明您需要找到 所有 input 节点,如果它们具有与 @for 值相同的 @idlabel 和文本 'Max Driving Time_h' 而你只需要 input 和对应的 label (注意 . 表示“上下文节点”)

根据您的样本,以下 XPath //input[@id=(//label[.='Max Driving Time_h']/@for)] 不起作用,因为 :

  • "Max Driving Time_h" 文本包含在 mat-label 节点内,而不是 一个label一个。
  • @for 属性属于那个 label 节点。

您可以通过多种方式修复 XPath。不要忘记 add (...)[1] 以获得第一个结果:

(//input[@id=//mat-label[.='Max Driving Time_h']/../@for])[1]
(//input[@id=//label[./mat-label[.="Max Driving Time_h"]]/@for])[1]

也就是说,要更短、更高效,只需使用:

//input[./following::mat-label[.='Max Driving Time_h']]