How do I find the number of xpaths of Type A that are between two xpaths of Type B?

Viewed 52

I’m trying to pull information from an online hockey game summary about penalties assessed during the game.

The penalties each have xpath:

[…]/div/div[x]/h4

where x is the number of the penalty

Inbetween, there are labels for the period the penalties occurred in, which have xpath:

[…]/div/h3[y]

where y is the number of the period.

The problem is, the start of a new period doesn’t reset the penalty number, and the summary looks like:

First period ([…]/div/h3[1])  
Penalty1 ([…]/div/div[1]/h4)  
Penalty2 ([…]/div/div[2]/h4)  
Second period ([…]/div/h3[2])  
Penalty3 ([…]/div/div[3]/h4)  
Penalty4 ([…]/div/div[4]/h4)  
Penalty5 ([…]/div/div[5]/h4)  
Third period ([…]/div/h3[3])  
Penalty6 ([…]/div/div[6]/h4)  

And obviously, different games have different penalty numbers.

Is there a way I can find how many penalties were assessed in each period of a given game?
In the example above, I would want to know that there were 2 penalties in the first period, 3 in the second, and 1 in the third.

There are CSS selectors I could use in theory, but I'm not sure how I could use them: Every penalty has CSS selector

div class=“boxscore-event-ctn"

and every period has CSS selector

h3 class=“margT40"

However, those same CSS selectors are also used for other elements in the HTML code.

Thank you!!

EDIT: Here's the relevant section of the HTML for a sample game. This game had no penalties in the first period, 3 in the second, and 2 in the third:

      <div id="tabcontent102">
        <div class="pad40" style="background-image:none;">
          <h2>Penalties summary</h2>
          <h3 class="margT40">First Period</h3><span>No penalty</span>  
          <h3 class="margT40">Second period</h3>
          <div class="boxscore-event-ctn"><img style="width:40px;height:40px;float:left;"src="https://cdn.wssmedias.com/websimhockey/logos/LHSVL/Toronto.jpg">. 
            <h4>15:26 T. BERTUZZI (Rudesse)</h4>
            <div class="flowfix"></div>
          </div>
          <div class="boxscore-event-ctn"><img style="width:40px;height:40px;float:left;"src="https://cdn.wssmedias.com/websimhockey/logos/LHSVL/Toronto.jpg">. 
            <h4>09:40 M. CARLE (Avoir retenu)</h4>
            <div class="flowfix"></div>
          </div>
          <div class="boxscore-event-ctn"><img style="width:40px;height:40px;float:left;"src="https://cdn.wssmedias.com/websimhockey/logos/LHSVL/SanDiego.jpg">. 
            <h4>05:58 J. JOHNSON (Faire trébucher)</h4>
            <div class="flowfix"></div>
          </div>
          <h3 class="margT40">Third period</h3>
          <div class="boxscore-event-ctn"><img style="width:40px;height:40px;float:left;"src="https://cdn.wssmedias.com/websimhockey/logos/LHSVL/SanDiego.jpg"> 
            <h4>13:33 J. BOLL (Trop de joueurs sur la glace - banc)</h4>
            <div class="flowfix"></div>
          </div>
          <div class="boxscore-event-ctn"><img style="width:40px;height:40px;float:left;"src="https://cdn.wssmedias.com/websimhockey/logos/LHSVL/SanDiego.jpg">  
            <h4>06:36 B. BURNS (Avoir accroché)</h4>
            <div class="flowfix"></div>
          </div>
          <h3 class="margT40">Overtime</h3><span>No penalty</span></div>
      </div>
1 Answers

This answer shows how to get information between 2 known elements using XPath.
Please note that XPath 1.0 is implemented by many languages so the shown results are based on the xpath expression and not the language or utility (xmllint in this case).

Get the count of penalties on second period

XPath

All in a single line
count(//div[@id="tabcontent102"]//div[@class="boxscore-event-ctn" and ./preceding-sibling::h3[.="Second period"] and not(./preceding-sibling::h3[.="Third period"])]/h4)

Test with xmllint

xmllint --html --xpath 'count(//div[@id="tabcontent102"]//div[@class="boxscore-event-ctn" and ./preceding-sibling::h3[.="Second period"] and not(./preceding-sibling::h3[.="Third period"])]/h4)' test.html ; echo

Result:

3

To get the third period, change the test values in the predicates
count(//div[@id="tabcontent102"]//div[@class="boxscore-event-ctn" and ./preceding-sibling::h3[.="Third period"] and not(./preceding-sibling::h3[.="Overtime"])]/h4)

Using element position instead of value

Xpath

//div[@id="tabcontent102"]//div[@class="boxscore-event-ctn" and ./preceding-sibling::h3[3] and not(./preceding-sibling::h3[4])]/h4/text()

Getting h4 text value on command line

(echo 'cat //div[@id="tabcontent102"]//div[@class="boxscore-event-ctn" and ./preceding-sibling::h3[3] and not(./preceding-sibling::h3[4])]/h4/text()') | xmllint --html --shell test.html 

Result:

/ > cat //div[@id="tabcontent102"]//div[@class="boxscore-event-ctn" and ./preceding-sibling::h3[3] and not(./preceding-sibling::h3[4])]/h4/text()
 -------
13:33 J. BOLL (Trop de joueurs sur la glace - banc)
 -------
06:36 B. BURNS (Avoir accroch&Atilde;&copy;)

Get count on last element

Xpath

count(//div[@id="tabcontent102"]//h3[.="Overtime"]/following-sibling::div[@class="boxscore-event-ctn"])

Using h3 position
count(//div[@id="tabcontent102"]//h3[4]/following-sibling::div[@class="boxscore-event-ctn"])

Related