简体   繁体   English

XPath:基于后续元素中的文本选择元素吗?

[英]XPath: Select Element Based on Text in Following Element?

I have the following HTML snippet 我有以下HTML代码段

    <div class="a-expander-content a-spacing-base a-expander-inline-content a-expander-inner a-expander-content-expanded" style="" aria-expanded="true">
    <form id="pp-yT-23" class="pmts-add-credit-card-form pmts-portal-component pmts-portal-components-pp-yT-8 a-spacing-none" data-pmts-component-id="pp-yT-8" data-pmts-ajax-continuation="true" action="https://www.bbc.com/gp/w/ref=w?w=UTF8&_encoding=UTF8&<input class="a-button-input" type="submit" aria-labelledby="pp-yT-32-announce" name="ppw-widgetEvent:AddCreditCardEvent"/>
<span id="pp-yT-32-announce" class="a-button-text" aria-hidden="true">Add your card</span>=1&startingView=VIEW_INSTRUMENT_LIST" method="post">
    <input type="hidden" value="4|MXzCdjmqmSKRqcnRhGeW4iH0AQ-hnQ-2gnP1pGe3ibFlVEzK2Jwpm6KcMxCyOiJRtzKNCVbR1QBo2mfUL8Jbc5DnErF8cuPgQP15-EhnY_vDCMIm1igDBGrOR1-G_664V7rgc5fmYMvW5bguQ8NOEHJkM2t2JA2no4zG6ALkPg2hCUOnUyhTkAk3CWOP5c2HI_ml4criD9lV4VYbVWqpkGNtXQHT6GusM9rYxALSwjNdV9EuUtMbXhNdQrNNeIoELCjMHsrvFL2Qs70Bu0nh6SnpQ9bCS6r9rBBSKDWCezCRJZZqyQFDk8pvtZqUgyriWBS9uBwNKvqRO6P6jTRJYX5H0dGqkclvjL2R_J7HOuirDH6fwxplisgG48bZXCCSDICIXOKUF18PctRw74G-2e1-ZKD2IqZ-Efsjyel2SLSvBrEqV_d8dp7Sm7p_DNFtty7hhcinmB5Ej4VHFk4HCkAlx64Yex0hFV3yc3B3m4moPryyy75m9Fe4oa1KiZnORWF8EKbjAI7gFjhuTfpVdRZDiS-rtC7uahA4ZnR8ZMyEX223dvW1xF6RKSmwAtpES-9kk_PVy9fr7uvWyzzoGwNYFXtunYeo59bqDEGvomW6djTUMJAi2Xpn-06Sf45qhZytKe66ooTvy6l7yI_fpwhofaFvSj_hcFBkDXfDScsShk0EksXZi4YZynZbCBDocj61XslqJcj0NzY8nNi5AnD_UbOV5WS2PotxdzTMdFFABj-xtW72-aO_vEdoJ0LH0OOdOp8uwFm4sIHRoatIO5ced_v9_iceOt-j6uYlWxJsrf653X9s_rwdkF4z5u4e6UZ2askDGXEPI9wBReQhU8DafQM4JVsYfW-V1TXjkZipZIiEL-R5gxCBiRzi_tLY0YO_nlgXKxPPUytxXL_321837OfvmkbqY67uFvHemgSbxP2Y_4PzMatJ3uOpOiNHcC7vHMImbd8MzFTZDhdAlsfcCmEaeIRYudEh3L2b339J5yFxiWyeGosuY7deRUHeUOFSF9HkRBg2uXQMN8BlsbcYgWXdC5fjUbAoKXMTYYg_cxtTNViU-FgWw1fXvCyfot0idPpxOEweLLUIBfher25SwP6LMcipWIyFJlo4RPWqcIk4LbLJ4xAuuaX8b9Bwmo4yc9cFWGd1wuM3IJbWWTyPuJwHamgn3pDYkvimctFBHi3voq1xi6pxBXBSm75ara_t-cK1KVGYBz69fct3lQVVJTfYfCKu9JlYQz4GooylMcNIt5CqDEZK7i4cwwPDKtH9-yqLcodolmdFnbMamyK4cHNoRub_WbfHeXqw28pVeKE045ptD-xLMJOHAzMhdfH37SAUQ8eiOhug4jcymETMtlzHTVD1gQ-CyQ1bQWvUhWhW8gtvaGv5Wd6VUicmEBZ4mhLcc68MW_DQ9k2oyNkAvEb0HZgO9wB20hXGPpXSeBCElHjVBV3LDthYyDz829Vva-6iXkd3C5BQmEOaqjY8D0Key77bEL8cc-Dr35eMGv0oewGAjEnh_dBiuQ3jcw0q_yH8zDkRwz2x86Le8QC267W3R-b0zIqUqo_XdN2U2JZiVSmwXNH17Nz9RMgZRxYOzNXLEcmLkA1zR0b3z91L1XLGJ2LR8wq6HQLnx-17J_yxHRyMEiDa62rxITvsIqqAt4jXxLTtwvKOhtwVnyONrInjkWgaMUVtmlgIOCbLJi_rIW2rn7A4JO7qg" name="ppw-widgetState"/>
    <div id="pp-yT-24" class="a-row a-spacing-base a-hidden aok-hidden">
    <div class="a-row a-spacing-base">Enter your card information:</div>
    <div class="a-row a-spacing-base">
    <div class="a-section a-spacing-none pmts-inline-field-block">
    <div class="a-section a-spacing-none pmts-inline-field-block">
    <div class="a-section a-spacing-none a-spacing-top-large pmts-inline-field-block">
    <div class="a-section a-spacing-none pmts-inline-field-block">
    <div class="a-section a-spacing-none pmts-inline-field-block pmts-inline-add-button-spacing-top">
    <span id="pp-yT-32" class="a-button a-button-primary pmts-button-input">
    <span class="a-button-inner">
    <input class="a-button-input" type="submit" aria-labelledby="pp-yT-32-announce" name="ppw-widgetEvent:AddCreditCardEvent"/>
    <span id="pp-yT-32-announce" class="a-button-text" aria-hidden="true">Add your card</span>
    </span>
    </span>
    </div>
    </div>
    <div class="a-checkbox pmts-update-everywhere-checkbox a-spacing-base" data-a-input-name="ppw-updateEverywhereAddCreditCard">
    </form>
    </div>
    </div>
    </div>
    <hr class="a-divider-normal"/>
    <div class="a-row a-spacing-base pmts-portal-component pmts-portal-components-pp-yT-13" data-pmts-component-id="pp-yT-13">
    <hr class="a-divider-normal"/>
    <div id="pp-yT-34" class="a-section pmts-portal-component pmts-portal-components-pp-yT-14" data-pmts-component-id="pp-yT-14">
    </div>
    </div>
    </div>

Based on the HTML snippet above: 根据上面的HTML代码段:

<input class="a-button-input" type="submit" aria-labelledby="pp-yT-32-announce" name="ppw-widgetEvent:AddCreditCardEvent"/>
<span id="pp-yT-32-announce" class="a-button-text" aria-hidden="true">Add your card</span>

I'm to select the button/input element using the following XPath: 我将使用以下XPath选择按钮/输入元素:

    //span[@type='submit' and contains ( ., 'Add your card')]

But I am unable to select anything. 但我无法选择任何东西。 I'm assuming this may be bec the text "Add your card" is not actually part of the input element but the span element. 我假设这可能是因为“添加您的卡”文本实际上不是输入元素的一部分,而是span元素。 So my question is - can I select a button/input element based on the text in the following element? 所以我的问题是-我可以根据以下元素中的文本选择按钮/输入元素吗?

Pls note I understand how to select an element based on the text in element but here the text is not actually in the element itself (although it appears embedded in the element on the screen) but rather in the next element.. I also understand I could select the element based on the name attribute but this is not what I want. 请注意,我了解如何根据元素中的文本选择元素,但此处的文本实际上并不存在于元素本身中(尽管它似乎嵌入在屏幕上的元素中),而是在下一个元素中。.我也理解我可以根据name属性选择元素,但这不是我想要的。

Thanks 谢谢

OK I figure out the error thought I'd share the solution with others. 好的,我发现错误是因为我想与他人共享解决方案。

Basically, I need to use something like: 基本上,我需要使用类似:

    //span[contains ( ., 'Add your card')]

Or a even better solution (as posted by @Sudeepthi) would be: 或者更好的解决方案(如@Sudeepthi发布)将是:

    //span[contains(text(),'Add your card')]

And omit: 并省略:

    [@type='submit']

Because the two attributes are part of two different elements. 因为这两个属性是两个不同元素的一部分。

However I'm still not sure if it's possible to combine two attributes like this if I wanted to? 但是,我仍然不确定是否可以将这样的两个属性组合在一起?

Your XPATH expression ... 您的XPATH表达式...

//span[@type='submit' and contains ( ., 'Add your card')]

... selects <span> elements having an attribute type with value submit . ...选择<span>具有属性的元素type与值submit Your <span> does not have such an attribute, and it's not the element you say you want to select anyway (since you say you want to select the <input> element). 您的<span>没有这样的属性,也不是您说要选择的元素(因为您说要选择<input>元素)。

Possibly you want something like this: 您可能想要这样的东西:

//span[contains ( ., 'Add your card')]/preceding-sibling::input[position() = 1 and @type='submit']

That locates the wanted <input> element by first identifying the <span> carrying the label, then stepping backward to its immediately-preceding <input> sibling (if any) and checking its type. 通过首先标识带有标签的<span> ,然后退回到其紧接的<input>同级(如果有)并检查其类型,从而找到所需的<input>元素。

can I select a button/input element based on the text in the following element? 可以基于以下元素中的文本选择按钮/输入元素吗?

Yes, you can locate locate desire <input> element wrt as Add your card as below :- 是的,您可以如下所示找到所需的<input>元素wrt作为Add your card :-

.//span[@class='a-button-inner' and span[text()='Add your card']]/input[@type='submit']

You can also locate this <input> element using cssSelector as below :- 您也可以使用cssSelector定位此<input>元素,如下所示:-

input.a-button-input[type='submit'][name*='AddCreditCardEvent']

If <span class="a-button-inner"> element is also clickable, I would suggest try using normalize-space() function of the xpath which strips leading and trailing white-space from a string, replaces sequences of whitespace characters by a single space, and returns the resulting string instead of contains() as below :- 如果<span class="a-button-inner">元素也是可点击的,我建议尝试使用xpath normalize-space()函数,该函数从字符串中xpath前导和尾随空格,将空格字符序列替换为一个空格,然后返回结果字符串,而不是contains() ,如下所示:-

.//span[normalize-space(.)='Add your card' and @class='a-button-inner']

Or for parent <span> :- 或对于父<span> :-

.//span[normalize-space(.)='Add your card']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM