jquery selectors: an uncommon use case

2019-09-04 04:44发布

I have to parse an html page organized this way:

<li id="list">
  <a id="cities">Cities</a>
  <ul>
    <li>
      <a class="region" title="liguria">Liguria</a>
      <ul>
        <li>
          <a class="genova">Genova</a>
        </li>
        <li>
          <a class="savona">Savona</a>
        </li>
      </ul>
    </li>
    <li>
      <a class="region" title="lazio">Lazio</a>
      <ul>
        <li>
          <a class="roma">Roma</a>
        </li>
      </ul>
    </li>
  </ul>
</li>

I need to extract a list of all the cities. I don't care about regions... I am using cheerio from node.js, but I added jquery to the tags since cheerio uses jquery-style selector (AFAIK...).

I have come with this partial solution, partially working (it only lists first region group cities...):

$('li[id="list"] li li').each(function(i, elem) {
  console.log('city:', elem.children[0].next.children[0].data);
});

As you can see, I'm quite confused... :-(
Any clue?

3条回答
老娘就宠你
2楼-- · 2019-09-04 05:12

Try: $('li#list ul li ul li a').each(function() { console.error("City: "+$(this).html()); });

As noted below, the selector could be simply $('li#list li li a').

查看更多
等我变得足够好
3楼-- · 2019-09-04 05:19

Note that when using an id selector, since by definition an id is unique, the selector does not need any other qualifiers such as the tag name. And usually you would only use tagname[id...] if you're matching a substring in the ID: ^ - at the beginning, $ - at the end or * - anywhere.

Another approach would be to use :not() to exclude the a elements that should be left out:

$('#list a:not(.region,#cities)').each(function(i, a) {
    console.log( i, a.innerHTML );
}); 

You have several options for valid selectors you can use:

  • #list ul ul a
  • #list li li a
  • #list ul ul li a

$('#list a:not(.region,#cities)').each(function(i, a) {
    console.log( i, a.innerHTML );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="list">
  <a id="cities">Cities</a>
  <ul>
    <li>
      <a class="region" title="liguria">Liguria</a>
      <ul>
        <li>
          <a class="genova">Genova</a>
        </li>
        <li>
          <a class="savona">Savona</a>
        </li>
      </ul>
    </li>
    <li>
      <a class="region" title="lazio">Lazio</a>
      <ul>
        <li>
          <a class="roma">Roma</a>
        </li>
      </ul>
    </li>
  </ul>
</li>

AND to get all the cities in an array called cities you can use the jQuery .map() method:

var cities = $('#list li li a').map(function() {
    return this.innerHTML;
}).get();

var cities = $('#list li li a').map(function() {
    return this.innerHTML;
}).get();
console.log( cities );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="list">
  <a id="cities">Cities</a>
  <ul>
    <li>
      <a class="region" title="liguria">Liguria</a>
      <ul>
        <li>
          <a class="genova">Genova</a>
        </li>
        <li>
          <a class="savona">Savona</a>
        </li>
      </ul>
    </li>
    <li>
      <a class="region" title="lazio">Lazio</a>
      <ul>
        <li>
          <a class="roma">Roma</a>
        </li>
      </ul>
    </li>
  </ul>
</li>

查看更多
叛逆
4楼-- · 2019-09-04 05:25

Try this

$('li[id="list"] ul li').each(function(i, elem) {
     ...work on each li containing the region ...
});
查看更多
登录 后发表回答