./* means child "elements" as in <b><i></i><em></em></b>, the child elements of b are i and em, there is two
Saying not(./*) mean no child elements
self::text() means select text node children
Saying not(self::text()) select nodes that are not text nodes, as in <p>text</p> p would be an "element" and "text" would be a child node of type text ... don't want those, just the P
Together they mean not have children and is not text nodes
What I remember of xpath is you'd write it like this
## select any "element" with no kids and no text
/descendant-or-self::node()[
not(./*)
and
not(self::text())
]
But apparently ( http://www.w3.org/TR/xpath ) and conditions are also represented with stacking [][][] so its equivalent to /descendant-or-self::node()
[not(./*)]
[not(self::text()]
Although, you can simply select element nodes with no element children //*[ not(./*) ] |