ee clipse
ee clipse

Reputation: 245

XPath: Select Element Based on Text in Following Element?

I have the following HTML snippet

    <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:

<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:

    //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. 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.

Thanks

Upvotes: 2

Views: 2670

Answers (3)

Saurabh Gaur
Saurabh Gaur

Reputation: 23835

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 :-

.//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 :-

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[normalize-space(.)='Add your card' and @class='a-button-inner']

Or for parent <span> :-

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

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 181469

Your XPATH expression ...

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

... selects <span> elements having an attribute type with value 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).

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.

Upvotes: 0

ee clipse
ee clipse

Reputation: 245

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:

    //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?

Upvotes: 0

Related Questions