Search code examples
javascripthtmlxpath

Xpath of element based only in text content?


I'm trying to get the xpath of the second button "buy" for this HMTL code, but without using class, id nor other attribute nor full Xpath, only the text content relative to it like in this examples . The code has 2 "ul" elements within a "div". Each "ul" has 3 or 4 "li". I want like this since the internal attributes chang, but the structure and text content remains.

My goal is have the Xpath of the second "Buy", this is, the one related with the "li" that contains the text "Home".

My attempts in Chrome console so far are like below, but is not working:

$x("//*[text()='Home']")
$x("//ul[text()='Home']")
$x("//*[text()='Home']/following-sibling::li")

In the image below I show it.

enter image description here

div {
    background-color:#eeeeee;
    display:inline;      
}

#ul li {
  display: grid;
    column-count: 4;
    column-gap: 20px;
    display: inline;
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>

<div>
<ul>
    <li data-dqa-li="" data-components="xyzq-li" id="daw48" class="daw-view"><div data-components="xyzq-li-row" id="daw49" class="xyzq-list-item section-title daw-view"><div class="xyzq-list-column flex-width ">
                <div class="xyzq-list-item">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item inner-list-item " style="">
                            <div class="xyzq-list-column flex-width column-unshrink ">
                                <div class="xyzq-list-item">
                                    <div class="xyzq-list-column main-text section-title-text" dir="ltr" data-dqa-message="">
                                                Electronics
                                    </div>
                                </div>
                                <!----><!----><!----><!----></div>
                        </div>
                    </div>
                    <!----><!----></div>
            </div>
        </div></li>
    <li data-dqa-li="" data-components="xyzq-li" id="daw50" class="daw-view"><div data-components="xyzq-li-row" id="daw51" class="xyzq-list-item daw-view"><div class="xyzq-list-column flex-width fixed-width">
                <div class="xyzq-list-item">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item inner-list-item " style="">
                            <div class="xyzq-list-column flex-width column-unshrink ">
                                <div class="xyzq-list-item">
                                    <div class="xyzq-list-column main-text description-regular" dir="ltr" data-dqa-message="">
                                                Cameras
                                    </div>
                                </div>
                                <!----><!----><!----><!----></div>
                        </div>
                    </div>
                    <!----></div>
            </div>
            <div class="xyzq-list-column flex-width ">
                <div class="xyzq-list-item">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item inner-list-item " style="">
                            <div class="xyzq-list-column flex-width column-unshrink ">
                                <div class="xyzq-list-item">
                                    <div class="xyzq-list-column main-text bold-text description-regular" dir="ltr" data-dqa-message="">
                                                4K Front
                                    </div>
                                </div>
                                <!----><!----><!----><!----></div>
                        </div>
                    </div>
                    <!----><div class="xyzq-list-column column-unshrink button-column ">
                        <div data-components="xyzq-button" id="daw52" class="list-cam-narrow-button expand-taparea button daw-view"><button tabindex="0" class="secondary-button row-button text-button disabled-loading-caption" data-dqa-button="secondary" type="button"><span dir="ltr" class="caption">Buy</span></button>
                        </div>
                    </div>
                </div>
            </div>
        </div></li>

</ul>

<ul>
    <li data-dqa-li="" data-components="xyzq-li" id="daw48" class="daw-view"><div data-components="xyzq-li-row" id="daw49" class="xyzq-list-item section-title daw-view"><div class="xyzq-list-column flex-width ">
                <div class="xyzq-list-item">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item inner-list-item " style="">
                            <div class="xyzq-list-column flex-width column-unshrink ">
                                <div class="xyzq-list-item">
                                    <div class="xyzq-list-column main-text section-title-text" dir="ltr" data-dqa-message="">
                                                Home
                                    </div>
                                </div>
                                <!----><!----><!----><!----></div>
                        </div>
                    </div>
                    <!----><!----></div>
            </div>
        </div></li>
    <li data-dqa-li="" data-components="xyzq-li" id="daw50" class="daw-view"><div data-components="xyzq-li-row" id="daw51" class="xyzq-list-item daw-view"><div class="xyzq-list-column flex-width fixed-width">
                <div class="xyzq-list-item">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item inner-list-item " style="">
                            <div class="xyzq-list-column flex-width column-unshrink ">
                                <div class="xyzq-list-item">
                                    <div class="xyzq-list-column main-text description-regular" dir="ltr" data-dqa-message="">
                                                Appliances
                                    </div>
                                </div>
                                <!----><!----><!----><!----></div>
                        </div>
                    </div>
                    <!----></div>
            </div>
            <div class="xyzq-list-column flex-width ">
                <div class="xyzq-list-item">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item inner-list-item " style="">
                            <div class="xyzq-list-column flex-width column-unshrink ">
                                <div class="xyzq-list-item">
                                    <div class="xyzq-list-column main-text bold-text description-regular" dir="ltr" data-dqa-message="">
                                                Fans
                                    </div>
                                </div>
                                <!----><!----><!----><!----></div>
                        </div>
                    </div>
                    <!----><div class="xyzq-list-column column-unshrink button-column ">
                        <div data-components="xyzq-button" id="daw52" class="list-cam-narrow-button expand-taparea button daw-view"><button tabindex="0" class="secondary-button row-button text-button disabled-loading-caption" data-dqa-button="secondary" type="button"><span dir="ltr" class="caption">Buy</span></button>
                        </div>
                    </div>
                </div>
            </div>
        </div></li>
    <li data-dqa-li="" data-components="xyzq-li" id="daw53" class="daw-view"><button data-dqa-button="list" tabindex="0" data-components="xyzq-li-button-row" id="daw54" class="daw-view"><div class="xyzq-list-item ">
                <div class="xyzq-list-column flex-width ">
                    <div class="xyzq-list-item">
                        <div class="xyzq-list-column flex-width ">
                            <div class="xyzq-list-item inner-list-item " style="">
                                <div class="xyzq-list-column flex-width column-unshrink ">
                                    <div class="xyzq-list-item">
                                        <div class="xyzq-list-column main-text description-regular" dir="ltr" data-dqa-message="">
                                                Discount Code
                                        </div>
                                    </div>
                                    <!----><!----><!----><!----></div>
                            </div>
                        </div>
                        <div class="xyzq-list-column column-unshrink icon-drilldown " title="Select" data-dqa-img="drilldown"/>
                        <!----></div>
                </div>

            </div>
        </button></li>
</ul>



</div>
</body>
</html>


Solution

  • To match an element by text the contains() can be used (as already suggested in the comments).

    A following-sibling part is correct and should be followed by a button expression.

    //li[contains(., "Home")]/following-sibling::li//button[contains(., "Buy")]
    

    document.getElementById('find').addEventListener('click', () => {
      const xpath = '//li[contains(., "Home")]/following-sibling::li//button[contains(., "Buy")]';
      const buy = document.evaluate(xpath, document, null,
        XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
      buy.style.background = 'green';
    });
    div {
      background-color: #eeeeee;
      display: inline;
    }
    
    #ul li {
      display: grid;
      column-count: 4;
      column-gap: 20px;
      display: inline;
    }
    
    #find {
      font-weight: bold;
    }
    <div>
      <ul>
        <li data-dqa-li="" data-components="xyzq-li" id="daw48" class="daw-view">
          <div data-components="xyzq-li-row" id="daw49" class="xyzq-list-item section-title daw-view">
            <div class="xyzq-list-column flex-width ">
              <div class="xyzq-list-item">
                <div class="xyzq-list-column flex-width ">
                  <div class="xyzq-list-item inner-list-item " style="">
                    <div class="xyzq-list-column flex-width column-unshrink ">
                      <div class="xyzq-list-item">
                        <div class="xyzq-list-column main-text section-title-text" dir="ltr" data-dqa-message="">
                          Electronics
                        </div>
                      </div>
                      <!---->
                      <!---->
                      <!---->
                      <!---->
                    </div>
                  </div>
                </div>
                <!---->
                <!---->
              </div>
            </div>
          </div>
        </li>
        <li data-dqa-li="" data-components="xyzq-li" id="daw50" class="daw-view">
          <div data-components="xyzq-li-row" id="daw51" class="xyzq-list-item daw-view">
            <div class="xyzq-list-column flex-width fixed-width">
              <div class="xyzq-list-item">
                <div class="xyzq-list-column flex-width ">
                  <div class="xyzq-list-item inner-list-item " style="">
                    <div class="xyzq-list-column flex-width column-unshrink ">
                      <div class="xyzq-list-item">
                        <div class="xyzq-list-column main-text description-regular" dir="ltr" data-dqa-message="">
                          Cameras
                        </div>
                      </div>
                      <!---->
                      <!---->
                      <!---->
                      <!---->
                    </div>
                  </div>
                </div>
                <!---->
              </div>
            </div>
            <div class="xyzq-list-column flex-width ">
              <div class="xyzq-list-item">
                <div class="xyzq-list-column flex-width ">
                  <div class="xyzq-list-item inner-list-item " style="">
                    <div class="xyzq-list-column flex-width column-unshrink ">
                      <div class="xyzq-list-item">
                        <div class="xyzq-list-column main-text bold-text description-regular" dir="ltr" data-dqa-message="">
                          4K Front
                        </div>
                      </div>
                      <!---->
                      <!---->
                      <!---->
                      <!---->
                    </div>
                  </div>
                </div>
                <!---->
                <div class="xyzq-list-column column-unshrink button-column ">
                  <div data-components="xyzq-button" id="daw52" class="list-cam-narrow-button expand-taparea button daw-view"><button tabindex="0" class="secondary-button row-button text-button disabled-loading-caption" data-dqa-button="secondary" type="button"><span dir="ltr" class="caption">Buy</span></button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </li>
    
      </ul>
    
      <ul>
        <li data-dqa-li="" data-components="xyzq-li" id="daw48" class="daw-view">
          <div data-components="xyzq-li-row" id="daw49" class="xyzq-list-item section-title daw-view">
            <div class="xyzq-list-column flex-width ">
              <div class="xyzq-list-item">
                <div class="xyzq-list-column flex-width ">
                  <div class="xyzq-list-item inner-list-item " style="">
                    <div class="xyzq-list-column flex-width column-unshrink ">
                      <div class="xyzq-list-item">
                        <div class="xyzq-list-column main-text section-title-text" dir="ltr" data-dqa-message="">
                          Home
                        </div>
                      </div>
                      <!---->
                      <!---->
                      <!---->
                      <!---->
                    </div>
                  </div>
                </div>
                <!---->
                <!---->
              </div>
            </div>
          </div>
        </li>
        <li data-dqa-li="" data-components="xyzq-li" id="daw50" class="daw-view">
          <div data-components="xyzq-li-row" id="daw51" class="xyzq-list-item daw-view">
            <div class="xyzq-list-column flex-width fixed-width">
              <div class="xyzq-list-item">
                <div class="xyzq-list-column flex-width ">
                  <div class="xyzq-list-item inner-list-item " style="">
                    <div class="xyzq-list-column flex-width column-unshrink ">
                      <div class="xyzq-list-item">
                        <div class="xyzq-list-column main-text description-regular" dir="ltr" data-dqa-message="">
                          Appliances
                        </div>
                      </div>
                      <!---->
                      <!---->
                      <!---->
                      <!---->
                    </div>
                  </div>
                </div>
                <!---->
              </div>
            </div>
            <div class="xyzq-list-column flex-width ">
              <div class="xyzq-list-item">
                <div class="xyzq-list-column flex-width ">
                  <div class="xyzq-list-item inner-list-item " style="">
                    <div class="xyzq-list-column flex-width column-unshrink ">
                      <div class="xyzq-list-item">
                        <div class="xyzq-list-column main-text bold-text description-regular" dir="ltr" data-dqa-message="">
                          Fans
                        </div>
                      </div>
                      <!---->
                      <!---->
                      <!---->
                      <!---->
                    </div>
                  </div>
                </div>
                <!---->
                <div class="xyzq-list-column column-unshrink button-column ">
                  <div data-components="xyzq-button" id="daw52" class="list-cam-narrow-button expand-taparea button daw-view"><button tabindex="0" class="secondary-button row-button text-button disabled-loading-caption" data-dqa-button="secondary" type="button"><span dir="ltr" class="caption">Buy</span></button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </li>
        <li data-dqa-li="" data-components="xyzq-li" id="daw53" class="daw-view"><button data-dqa-button="list" tabindex="0" data-components="xyzq-li-button-row" id="daw54" class="daw-view"><div class="xyzq-list-item ">
                    <div class="xyzq-list-column flex-width ">
                        <div class="xyzq-list-item">
                            <div class="xyzq-list-column flex-width ">
                                <div class="xyzq-list-item inner-list-item " style="">
                                    <div class="xyzq-list-column flex-width column-unshrink ">
                                        <div class="xyzq-list-item">
                                            <div class="xyzq-list-column main-text description-regular" dir="ltr" data-dqa-message="">
                                                    Discount Code
                                            </div>
                                        </div>
                                        <!----><!----><!----><!----></div>
                                </div>
                            </div>
                            <div class="xyzq-list-column column-unshrink icon-drilldown " title="Select" data-dqa-img="drilldown"/>
                            <!----></div>
                    </div>
    
                </div>
            </button></li>
      </ul>
    
    
    
    </div>
    
    <button id="find">FIND A BUTTON</button>