1

I am working with AJAX.

I make a GET request that returns a raw HTML string with the contents of a webpage. I am trying to find a way to extract all of the elements in between the opening and closing div tags:

<div role="main" class="main-container js-quickedit-main-content " style="padding:0px;margin:0px;"> 
    <!-- Trying to extract the children here -->
</div>

I've tried the following regex:

var div_result = result.match('(<div role="main" class="main-container js-quickedit-main-content " style="padding:0px;margin:0px;">)[^]*(</div>)').toString();

Which doesn't work properly. Over the div of .main-container, there is a div that contains this div. When I use this div, it returns the <\div> of the parent div, and not its own <\div>.

Is there any way to extract the text between the opening and closing div tags (<div ..> and </div>) which is only the first occurrence?


Edit: Added expected and actual results of the regex

This is what it's supposed to return:

<div role="main" class="main-container js-quickedit-main-content " style="padding:0px;margin:0px;">
  <div class="row">
    <!-- <div class="col-sm-12" role="heading"> -->
    <div role="heading">
      <div class="region region-header">
      </div>
    </div>
    <section>
      <a id="main-content"></a>
      <div class="region region-content">
        <section class="views-element-container block block-views block-views-blockabout-us-changing-images-block-3 clearfix" id="block-views-block-about-us-changing-images-block-3">
          <div class="form-group">
            <div class="view view-about-us-changing-images view-id-about_us_changing_images view-display-id-block_3 js-view-dom-id-f2624873734f13a6913b256416a10ff6d932a3677c7b77a637cdd2db4a34b6d8">
              <div class="view-content">
                <div class="about-images views-row">
                  <div class="views-field views-field-field__about-us-changing-image-2">
                    <div class="field-content"> <img src="/sites/default/files/2018-07/team_1.jpg" width="2000" height="1000" alt="team" typeof="foaf:Image" class="img-responsive" />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
        <nav role="navigation" aria-labelledby="block-aboutusteam-menu" id="block-aboutusteam">
          <h2 class="visually-hidden" id="block-aboutusteam-menu">About Us: Team</h2>
          <ul class="menu menu--about-us-team nav">
            <li class="expanded dropdown active">
              <a href="/about/team" class="dropdown-toggle" data-toggle="dropdown">OUR TEAM <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li>
                  <a href="/about" data-drupal-link-system-path="about">ABOUT US</a>
                </li>
                <li>
                  <a href="/about/careers" data-drupal-link-system-path="about/careers">CAREERS</a>
                </li>
                <li>
                  <a href="/about/locations" data-drupal-link-system-path="about/locations">LOCATIONS</a>
                </li>
              </ul>

            </li>
          </ul>
        </nav>
        <div class="views-element-container form-group">
          <div class="view view-about-us view-id-about_us view-display-id-page_3 js-view-dom-id-397ff9a567cc56e3cd5c3a241a47b938891ffac5bf429f45429bea3f12e2f041">
            <div class="view-content">
              <div class="nav-buttons"></div>
              <div class="nav-buttons"><span class="views-field views-field-field-menu-link-1"><span class="field-content nav-buttons"><a href="/about">ABOUT US</a></span></span> <span class="views-field views-field-field-menu-link-2"><span class="field-content nav-buttons"><a href="/about/careers">CAREERS</a></span></span>
                <span class="views-field views-field-field-menu-link-3"><span class="field-content nav-buttons"><a href="/about/team">OUR TEAM</a></span></span> <span class="views-field views-field-field-menu-link-4"><span class="field-content nav-buttons"><a href="/about/locations">LOCATIONS</a></span></span>
              </div>
              <div class="nav-buttons"></div>
              <div class="nav-buttons"></div>
              <div class="nav-buttons"></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </div>
</div>

This is what it actually returns:

<div role="main" class="main-container js-quickedit-main-content " style="padding:0px;margin:0px;">
  <div class="row">
    <!-- <div class="col-sm-12" role="heading"> -->
    <div role="heading">
      <div class="region region-header">
      </div>
    </div>
    <section>
      <a id="main-content"></a>
      <div class="region region-content">
        <section class="views-element-container block block-views block-views-blockabout-us-changing-images-block-3 clearfix" id="block-views-block-about-us-changing-images-block-3">
          <div class="form-group">
            <div class="view view-about-us-changing-images view-id-about_us_changing_images view-display-id-block_3 js-view-dom-id-b47f64080ec9b40e5e3c78370baead058f8da13fd70c4b5e10f54261cac8abef">
              <div class="view-content">
                <div class="about-images views-row">
                  <div class="views-field views-field-field__about-us-changing-image-2">
                    <div class="field-content"> <img src="/sites/default/files/2018-07/team_1.jpg" width="2000" height="1000" alt="team" typeof="foaf:Image" class="img-responsive" />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
        <nav role="navigation" aria-labelledby="block-aboutusteam-menu" id="block-aboutusteam">
          <h2 class="visually-hidden" id="block-aboutusteam-menu">About Us: Team</h2>
          <ul class="menu menu--about-us-team nav">
            <li class="expanded dropdown active">
              <a href="/about/team" class="dropdown-toggle" data-toggle="dropdown">OUR TEAM <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li>
                  <a href="/about" data-drupal-link-system-path="about">ABOUT US</a>
                </li>
                <li>
                  <a href="/about/careers" data-drupal-link-system-path="about/careers">CAREERS</a>
                </li>
                <li>
                  <a href="/about/locations" data-drupal-link-system-path="about/locations">LOCATIONS</a>
                </li>
              </ul>
            </li>
          </ul>
        </nav>
        <div class="views-element-container form-group">
          <div class="view view-about-us view-id-about_us view-display-id-page_3 js-view-dom-id-2550c3cf05f278ecbed10aa27942784678825c143bb247acf4fff74ae465e5b6">
            <div class="view-content">
              <div class="nav-buttons"></div>
              <div class="nav-buttons"><span class="views-field views-field-field-menu-link-1"><span class="field-content nav-buttons"><a href="/about">ABOUT US</a></span></span> <span class="views-field views-field-field-menu-link-2"><span class="field-content nav-buttons"><a href="/about/careers">CAREERS</a></span></span>
                <span class="views-field views-field-field-menu-link-3"><span class="field-content nav-buttons"><a href="/about/team">OUR TEAM</a></span></span> <span class="views-field views-field-field-menu-link-4"><span class="field-content nav-buttons"><a href="/about/locations">LOCATIONS</a></span></span>
              </div>
              <div class="nav-buttons"></div>
              <div class="nav-buttons"></div>
              <div class="nav-buttons"></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </div>
</div>
<footer class="footer container" role="contentinfo">
  <div class="region region-footer">
    <nav role="navigation" aria-labelledby="block-bootstrap-subtheme-footer-menu" id="block-bootstrap-subtheme-footer">
      <h2 class="visually-hidden" id="block-bootstrap-subtheme-footer-menu">Footer menu</h2>
      <ul class="menu menu--footer nav">
        <li>
          <a href="/contact" data-drupal-link-system-path="contact">Contact</a>
        </li>
      </ul>
    </nav>
  </div>
</footer>
</div>
Sam Holmes
  • 1,594
  • 13
  • 31
Hclee
  • 43
  • 2
  • 8
  • Possible duplicate of [regex lazy quantifier](https://stackoverflow.com/questions/28781874/regex-lazy-quantifier) (Not exact the same question, but it does answer the question) – Tezra Jul 17 '18 at 20:05
  • Why not innerHTML? – Emeeus Jul 17 '18 at 20:08
  • @Emeeus the variable of result contain all the text from to and i guess it makes the website heavy and slow, so I am trying to get specific divs with a class name that only have different contents. – Hclee Jul 17 '18 at 20:29
  • So to clarify: Using AJAX, you end up with a variable, containing an HTML string of an _entire_ webpage, and you're trying to extract certain elements from that webpage. Is that correct? – Sam Holmes Jul 17 '18 at 20:31
  • The edit you just made doesn't really clarify anything I'm afraid. It would be a great help if you could share the _actual_ code with the _actual_ desired outcome, otherwise we're kind of flying blind. – Sam Holmes Jul 17 '18 at 20:37
  • @SamHolmes well, I guess I need to add some text
    ..
    – Hclee Jul 17 '18 at 20:43
  • That's very helpful, thank you! :) Please could you also share the _entire_ webpage? – Sam Holmes Jul 17 '18 at 20:47

2 Answers2

2

Regex is probably not the best way to go about this.

The DOMParser is now widely supported in all major browsers, and allows you to turn an HTML string into a dummy DOM element that you can manipulate and perform operations on (same as any other genuine DOM element).

var htmlString = "<div role=\"main\" class=\"main-container js-quickedit-main-content\" style=\"padding:0px;margin:0px;\"><div>First child</div><div>Second child</div><div>Third child</div></div>";

var parser = new DOMParser();
var doc = parser.parseFromString(htmlString, "text/html");
var parent = doc.querySelector(".main-container");
var children = parent.childNodes;

children.forEach(child => console.log(child));
  • The new DOMParser().parseFromString() method accepts two arguments and returns a dummy HTML element that you can manipulate directly in javascript without ever creating an actual element in the DOM. The first argument is the string to parse, and the second is the type of text content (it can also parse XML)

  • I use Node.childNodes to retrieve the child elements

  • I use element.querySelector() in order to select the parent div that has a class of main-container

  • I use Array.prototype.forEach() to simply cleanly log out the children that are retrieved


The htmlString variable above is the equivalent of the following:

<div role="main" class="main-container js-quickedit-main-content" style="padding:0px;margin:0px;">
  <div>First child</div>
  <div>Second child</div>
  <div>Third child</div>
</div>
Sam Holmes
  • 1,594
  • 13
  • 31
  • Since the div of main-container has its parent div, i need to find a point where is its own , not its parent's – Hclee Jul 17 '18 at 20:22
  • I'm sorry, I don't understand. You said you needed to extract all the elements (the `...`) in between the opening and closing `div` tags. Which this does! If you have a further requirement beyond that, please update the snippet in your post to better demonstrate what you're _actually_ looking to do. – Sam Holmes Jul 17 '18 at 20:25
  • I am trying to only extract the content of
    ..
    , but what it returns are contents until of last content too since it is the same .
    – Hclee Jul 17 '18 at 20:38
  • I've updated the `querySelector` to only select the `.main-container` instead of a `div` with a `role` of `main`. Is that what you mean? – Sam Holmes Jul 17 '18 at 20:42
  • Oh, yes it is what i was exactly looking for! Thank you very much! – Hclee Jul 17 '18 at 20:46
  • Oh, sorry about all that confusion. Glad I could help in the end! :) – Sam Holmes Jul 17 '18 at 20:47
  • I am really sorry, but for another question, is there any specific reasons that it does not generate console, and it seems ajax not working sometimes. It refreshes a page instead of ajax function – Hclee Jul 17 '18 at 20:49
  • Unfortunately, that could happen for any reason. Your best bet is to ask a new question with the relevant section of AJAX code! – Sam Holmes Jul 17 '18 at 20:50
0

You match returns array of matches where first element is whole string, second element is div open tag, and the third is div closing tag. You should group content between tags, and take second element from array:

var result = '<div role="main" class="main-container js-quickedit-main-content " style="padding:0px;margin:0px;">... </div>';
var div_result = result.match('<div role="main" class="main-container js-quickedit-main-content " style="padding:0px;margin:0px;">([^]*)</div>')[1].toString();
alert(div_result);

and of course do not forget to check if match was found

trigras
  • 515
  • 6
  • 18
  • I guess my question is not clear. My question is like match stops at at first ocurrence. When I do mine or yours, it returns at last occurrence which is the parent's – Hclee Jul 17 '18 at 20:19