XPathで取ってきたテキストノードが意図した順番で来なかった
divの直下にテキストは好きじゃないけれど
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'> <html> <head> <meta http-equiv='Content-type' content='text/html; charset=utf-8'> <title>test</title> </head> <body> <div> <a href="hoge.php">hoge</a> | <a href="huga.cgi">huga</a> | <a href="piyo.php">piyp</a> </div> </body> </html>
こんなHTMLがあった場合、取ってきて欲しいテキストノードの順番は当然
[ 'hoge', ' | ', 'huga', ' | ', 'piyo' ]
でも、実際は
[ ' | ', 'hoge', ' | ', 'huga', 'piyo' ]
divのchildNodesをforeachで回すと、意図した通りに取れるのに、
PHPソースの一部
// DOM処理用に、参照文字にコンバート $data = mb_convert_encoding(上記HTML, 'HTML-ENTITIES', 'UTF-8'); $dom = new DOMDocument; @$dom->loadHTML($data); // nameとidの値が被るとエラーになるので、@で抑制 $xpath = new DOMXpath($dom); $query = '/html/body//text()[string-length(normalize-space()) > 0]'; $text_nodes = $xpath->query($query);
'[string-length(normalize-space()) > 0]'を外しても空白文字が混じるだけで順番変わらず。
htmlを直してみた
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'> <html> <head> <meta http-equiv='Content-type' content='text/html; charset=utf-8'> <title>test</title> </head> <body> <div> <a href="hoge.php">hoge</a><span> | </span><a href="huga.cgi">huga</a><span> | </span><a href="piyo.php">piyp</a> </div> </body> </html>
div直下のテキスト共(' | ')をsapnで優しく包み込んであげたら、意図した通りにノードが取れました。
ブロック要素の直下にテキストノードが来ていたら、span要素で囲む。って関数ないかな?