DOM level3 に対応したブラウザで使える、 javascript の document.evaluate であれば、XPath ですべてのコメントを抜き出すときに、
var result = document.evaluate("//comment()", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
等としておけば問題ないが、一部の HTML パーサでは、HTML の DOCTYPE 宣言もコメントとして扱ってしまうものがある。
…と言うより、 "<!" で始まって、">" で終わるものはすべてコメントとして扱ってしまうような場合について。
たとえば、.NET 向けの HTML パーサ HtmlAgilityPack がまさにそれなのだが、これを例に挙げてみる。
"//comment()[not(starts-with(translate(., 'CDEOPTY', 'cdeopty'), '<!doctype'))]"
XPath の述語の部分で、Docutype 宣言を検索から除外してやればよいわけだ。
starts-with 関数が大文字小文字を区別してしまうので、translate 関数で、すべて小文字に置き換え、 '<!doctype' と一致するかどうかをチェックしている。
HtmlAgilityPack の場合は、コメントの開始タグと終了タグも、コメントとして扱うため、starts-with 関数で比較する際に、コメントタグも含めているが、これはパーサの実装にも寄るので、適当に書き換えて欲しい。
(HtmlAgilityPack の場合、<!--comment--> 述部で比較対象になるのは、<!--comment--> 全体となるが、たとえば DOM lv.3 の evaluate の場合は、comment の部分だけになる)