Q:

How to find nodes that don't have certain child nodes

I could not find the exact question answered on this site.
The html on the page has many  elements, some of them contain header cells "tr", some actual data cells "td"
Here is an example:
<tr align="center">
    <th width="63"><b>&nbsp;</b></th>
    <th width="293"><b>Partners</b></th>
    <th width="54"><b>Score</b></th>
    <th width="184"><b>Type of Partner</b></th>
</tr>            
<tr>
 <td>&nbsp;</td>
 <td height="17">Acme trucking</td>
 <td align="center">0.75</td>
 <td>Truck Carrier</td>
</tr>

I need to find all "tr" elements that contain only "td" elements, in other words, exclude all that contain "th" elements
I would also like to have even more specific xpath expression that will find only "tr" elements that contain exactly 4 "td" child elements.
If you can provide 2 separate xpath expressions for just trs that have only "td"
and another one for "tr" that have exactlly 4 "td" I would really appreciate it.

A:

//tr[td and count(td) = count(*)] or //tr[td and not(*[not(self::td)])]
//tr[count(td) = 4 and count(td) = count(*)]

If you need tr with td only and without text, e.g.:
<root>
    <tr>
        Text here
        <td></td>
    </tr>
</root>

Suppose, it is not valid tr, you can use: 
//tr[td and count(td) = count(*) and not(normalize-space(text()))]

It allows only whitespaces.

