<?xml version="1.0" encoding="UTF-8" ?>
<feed
	xmlns="http://www.w3.org/2005/Atom"
	xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
	xml:lang="ja-JP"
>
	<title>私とHTML</title>
	<subtitle>最新15件を表示します。</subtitle>
	<id>tag:txqz.net,1970:/genre/HTML</id>
	<link rel="self" href="http://txqz.net/genre/HTML.atom"/>
	<link rel="alternate" type="application/rss+xml" href="http://txqz.net/genre/HTML.rdf"/>
	<link rel="alternate" type="application/xhtml+xml" href="http://txqz.net/genre/HTML.xhtml"/>
	<link rel="alternate" type="text/html" href="http://txqz.net/genre/HTML.html"/>
	<link rel="contents" href="http://txqz.net/genre" title="タグ一覧"/>
	<link rel="first" href="http://txqz.net/genre/%28%E7%A6%8F%29" title="(福)"/>
	<link rel="prev" href="http://txqz.net/genre/Hotmail" title="Hotmail"/>
	<link rel="next" href="http://txqz.net/genre/HTMLParser" title="HTMLParser"/>
	<link rel="last" href="http://txqz.net/genre/%EF%BD%83%EF%BD%83TLD" title="ｃｃTLD"/>
	<author>
		<name>陽坂智佐</name>
		<email>spambasket@txqz.net</email>
	</author>
	<entry>
		<title>PagingNavigatorが出すHTMLがアレなので直した</title>
		<id>tag:txqz.net,2008-07-19:/blog/2008/07/19/2005</id>
		<link rel="alternate" href="http://txqz.net/blog/2008/07/19/2005"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>たとえば「全部で100件ある記事を15件ずつ表示したい」というのをWicketでやるには<a href="http://wicket.sourceforge.net/apidocs/wicket/markup/html/list/PageableListView.html" title="PageableListView (Wicket 1.2-SNAPSHOT API)">PageableListView</a>と<a href="http://wicket.sourceforge.net/apidocs/wicket/markup/html/navigation/paging/PagingNavigator.html" title="PagingNavigator (Wicket 1.2-SNAPSHOT API)">PagingNavigator</a>を使う。PagingNavigatorはページャを自動に生成してくれる便利なクラスだが、生成されるHTMLが大変微妙で、たとえば「最初」へのリンクのテキストが"&lt;&lt;"、「次」へのリンクは"&gt;"となっている。もちろん「次」へのリンクにrel="next"などついているわけもなく、明らかにユーザビリティが低い。実際にWicketのソースからPagingNavigator.htmlを見ると以下のようになっていた:</p>
<pre><code class="java">&lt;wicket:panel&gt;
    &lt;a wicket:id="first"&gt;&amp;lt;&amp;lt;&lt;/a&gt;&amp;nbsp;&lt;a wicket:id="prev"&gt;&amp;lt;&lt;/a&gt;
    &lt;span wicket:id="navigation"&gt;
        &lt;a wicket:id="pageLink" href="#"&gt;&lt;span wicket:id="pageNumber"&gt;5&lt;/span&gt;&lt;/a&gt;
    &lt;/span&gt;
    &lt;a wicket:id="next"&gt;&amp;gt;&lt;/a&gt;&amp;nbsp;&lt;a wicket:id="last"&gt;&amp;gt;&amp;gt;&lt;/a&gt;
&lt;/wicket:panel&gt;</code></pre>
<p>そこで、PagingNavigatorを継承したクラスであるMyPagingNavigatorを作成する。</p>
<p>javaファイルのほうはPagingNavigatorをextendsした上で、PagingNavigator.javaを丸コピしておく。htmlファイルは:</p>
<pre><code class="html">&lt;wicket:panel&gt;
&lt;ol class="pager"&gt;
    &lt;li&gt;&lt;a rel="first" href="" wicket:id="first"&gt;最初&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a rel="prev" href="" wicket:id="prev"&gt;前&lt;/a&gt;&lt;/li&gt;
    &lt;li wicket:id="navigation"&gt;&lt;a wicket:id="pageLink" href="#"&gt;&lt;span wicket:id="pageNumber"&gt;5&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a rel="next" href="" wicket:id="next"&gt;次&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a rel="last" href="" wicket:id="last"&gt;最後&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/wicket:panel&gt;</code></pre>
<p>こんな感じ。ただ、実際に表示させてみたところちょっと気になるところがあった。</p>
<pre><code class="html">&lt;ol class="pager"&gt;
    &lt;li&gt;&lt;span rel="first"&gt;&lt;em&gt;最初&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span rel="prev"&gt;&lt;em&gt;前&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;&lt;em&gt;&lt;span&gt;1&lt;/span&gt;&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="hogehoge"&gt;&lt;span&gt;2&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="hogehoge" rel="next"&gt;次&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="hogehoge" rel="last"&gt;最後&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</code></pre>
<p>リンクがないときにa要素がspan要素とem要素に置き換わり、さらにspan要素にrel属性が残ってしまう。これでは気持ち悪いので、この変換がどこで行われるのか追いかけてみたけど分からなかった。時間があったらもっと詳しく見ていきたい。</p>
			</div>
		</content>
		<category term="Wicket"/>
		<category term="Java"/>
		<category term="HTML"/>
		<trackback:ping>http://txqz.net/blog/2008/07/19/2005/tb</trackback:ping>
		<published>2008-07-23T19:52:26+09:00</published>
		<updated>2008-07-23T20:02:21+09:00</updated>
	</entry>
	<entry>
		<title>Mozilla Java Html Parserが動いた</title>
		<id>tag:txqz.net,2008-06-19:/blog/2008/06/19/1424</id>
		<link rel="alternate" href="http://txqz.net/blog/2008/06/19/1424"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://txqz.net/blog/2008/01/24/1559" title="Mozilla Java Html Parserを使ってみた">5ヶ月前から放置して</a>いた<a href="http://mozillaparser.sourceforge.net/" title="Mozilla Java Html Parser">Mozilla Java Html Parser</a>だが、さっき入れなおしてみたら動いた。前回はMozillaHtmlParser.jarの中に入っていたcom.dappit.Dapper.parser.example.ParserExampleを参考にしたが、今回は<a href="http://mozillaparser.sourceforge.net/quickstart.html" title="Mozilla Java Html Parser">Quick Start</a>を参考にした、というかinitメソッドに渡す値が変だったのでそれを直せばよかったみたい。Quick Startに書いてあるとおりに、C:\Program Files\MozillaHtmlParser\mozilla.dist.bin.winとかを環境変数のPATHに加えたのだが、ソースにもその文字列をまた書くことになってしまった。多分もっと頭の良い方法があるのでそのうち調べる。</p>
<p>ソースは以下のとおり:</p>
<pre><code class="java">import java.io.File;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import com.dappit.Dapper.parser.EnviromentController;
import com.dappit.Dapper.parser.MozillaParser;

public class MJHP {
    public static void main(String[] args) throws Exception {
        File parserLibraryFile = new File("C:\\Program Files\\MozillaHtmlParser\\native\\bin\\MozillaParser" + EnviromentController.getSharedLibraryExtension()); 
        String parseLibrary = parserLibraryFile.getAbsolutePath(); 
        MozillaParser.init(parseLibrary, "C:\\Program Files\\MozillaHtmlParser\\mozilla.dist.bin.win"); 
        MozillaParser parser = new MozillaParser();
        Document document = parser.parse("&lt;html&gt;Hello world!&lt;/html&gt;");
        System.out.println(dom2string((Node)document.getDocumentElement()));
    }
    public static String dom2string(Node n) {
        StringBuilder buf = new StringBuilder();
        switch(n.getNodeType()) {
        case Node.TEXT_NODE :
            return n.getNodeValue();
        case Node.ELEMENT_NODE :
            buf.append(String.format("&lt;%s", n.getNodeName()));
            NamedNodeMap attrs = n.getAttributes();
            for(int i = 0; i &lt; attrs.getLength(); i++) {
                Node attr = attrs.item(i);
                buf.append(String.format(" %s=\"%s\"", attr.getNodeName(), attr.getNodeValue()));
            }
            buf.append("&gt;");
            for(Node child = n.getFirstChild(); child != null; child = child.getNextSibling()) {
                buf.append(dom2string(child));
            }
            buf.append(String.format("&lt;/%s&gt;", n.getNodeName()));
        }
        return buf.toString();
    }
}</code></pre>
<p>実行させると、以下のような出力を得られる:</p>
<pre><samp>Operating system : Windows XP
&lt;html&gt;&lt;body&gt;Hello world!&lt;/body&gt;&lt;/html&gt;
Initializing XPCOM from location : C:\Program Files\MozillaHtmlParser\mozilla.dist.bin.win...</samp></pre>
<p><a href="http://txqz.net/blog/2007/08/10/1200" title="ひどいHTMLをSAXパーサに読ませる">ひどいHTML特集</a>に<a href="http://txqz.net/blog/2007/08/10/1200#PS1213851391">Mozilla Java Html Parser編</a>を加えた。table直下にtbodyを補完するHTMLパーサは今のところこれだけ。その一方tr直下にtrが来てしまうなどの問題も見られた。</p>
			</div>
		</content>
		<category term="HTML"/>
		<category term="Java"/>
		<category term="パーサ"/>
		<category term="MozillaJavaHtmlParser"/>
		<trackback:ping>http://txqz.net/blog/2008/06/19/1424/tb</trackback:ping>
		<published>2008-06-19T14:24:09+09:00</published>
		<updated>2008-06-19T14:30:31+09:00</updated>
	</entry>
	<entry>
		<title>ホムペ作ったー＼(^o^)／</title>
		<id>tag:txqz.net,2008-06-09:/blog/2008/06/09/2105</id>
		<link rel="alternate" href="http://txqz.net/blog/2008/06/09/2105"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">

<p>勉強会メンバーの一人が<a href="http://hamq.jp/pc.html" title="無料ホームページ作成「ハムスター島」">ハムスター島</a>でホムペを運営しているとのことで私の中で空前のホムペブームが到来、そのままアカウントを取って<a href="http://www.hamq.jp/i.cfm?i=youzaka" title="txqz hamq">自分のホムペ</a>を立ち上げた。</p>
<p>動作確認かっこわらいをOpera9.27で取りつつ作成したため、Firefox2やIE6で見ると残念な結果になってしまった。FirefoxやIEで見るのは同一保持権の侵害かっこわらいなのでOperaユーザ率を高める意味も込めて皆さん<a href="http://jp.opera.com/" title="Opera ブラウザ: すべてのデバイスに最良のブラウザを">Opera</a>をぜひインストールしてアクセスしていきましょう！でも実際そんなの面倒だと思うので、下にキャプチャを置いておきますね＞＜</p>
<dl>
<dt>IE6</dt>
<dd><img src="/figure/2008/06/09/hamq_ie6029" alt="" /></dd>
<dt>Firefox2</dt>
<dd><img src="/figure/2008/06/09/hamq_firefox20014" alt="" /></dd>
<dt>Opera9</dt>
<dd><img src="/figure/2008/06/09/hamq_opera927" alt="" /></dd>
<dt>Safari3</dt>
<dd><img src="/figure/2008/06/09/hamq_safari311" alt="" /></dd>
</dl>
<p>きょうびはブログ全盛の世の中でみなさんなかなかホムペを持つこともないかもしれませんが、一つ作っておくと名刺代わりにもなっていいよ！オヌヌメ！</p>
<p>などのネタはともかく、気づいたところ:</p>
<ul>
<li><code class="html">&lt;isindex style="width: 10%; float: left;"&gt;</code>の処理。IEとSafariはstyle属性の指定を無視した。もともとisindexはhead要素の子となるべきものなので、style指定を無視するほうが妥当なのかもしれない。</li>
<li>marquee要素にstyle属性を指定するとFirefoxの表示が異常になった。marquee下にspanを追加し、そのspanにstyle属性を当てたところ改善された。(marqueeなのにposition:fixedなのがマズかった?)</li>
<li>plaintextがいったん始まればたとえ<code class="html">&lt;/plaintext&gt;</code>が現れようとかまわず文字列扱いにするブラウザがあった。さすがHTML4.0で廃止された要素タイプはレンダリングもやりたい放題だ。</li>
<li>さすがに<code class="html">&lt;script&gt;</code>や<code class="html">&lt;!--</code>は無効な文字列だとかでハネられた。</li>
</ul>
<p>iframeとかobjectとかはどうなるのかな? まあどうでもいいや。あと、最近はニコニコ動画とかもあるし、<a href="http://hatebutv.com/" title="はてブTV">はてブのコメントをニコニコ動画風に見るサービス</a>だってあるのだからmarqueeの復権があってもおかしくないのではないか。知らなかったんだけどmarqueeには以下のような愉快な属性が定義されているらしいぞ！ みんなでぜひ文字列を上下左右に動かそう！</p>
<table summary="marquee要素に定義されている主な属性を解説する5行3列の表です。">
<caption>marquee要素の主な属性</caption>
<thead>
<tr><th>属性名</th><th>属性値</th><th>意味</th></tr>
</thead>
<tbody>
<tr><th>behavior</th><td>scroll(初期値。一方向スクロール), slide(端にぶつかると停止), alternate(往復スクロール)</td><td>スクロールの仕方を指定。</td></tr>
<tr><th>direction</th><td>left(初期値。右から左), right(左から右), down(上から下), up(下から上)</td><td>スクロールの方向を指定。</td></tr>
<tr><th>scrollamount</th><td>数値</td><td>スクロールする量をピクセル単位で指定。</td></tr>
<tr><th>scrolldelay</th><td>数値</td><td>スクロール間隔をミリ秒単位で指定。</td></tr>
</tbody>
</table>
<p>ということで、熱に30分ほど浮かされて正気に戻りました。</p>
			</div>
		</content>
		<category term="自分のこと"/>
		<category term="ネタ"/>
		<category term="HTML"/>
		<category term="&lt;marquee&gt;"/>
		<trackback:ping>http://txqz.net/blog/2008/06/09/2105/tb</trackback:ping>
		<published>2008-06-09T21:05:58+09:00</published>
		<updated>2008-06-09T21:07:25+09:00</updated>
	</entry>
	<entry>
		<title>Mozilla Java Html Parserを使ってみた</title>
		<id>tag:txqz.net,2008-01-24:/blog/2008/01/24/1559</id>
		<link rel="alternate" href="http://txqz.net/blog/2008/01/24/1559"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://journal.mycom.co.jp/news/2008/01/22/024/index.html" title="Java Mozilla Html Parser登場、ブラウザと同じクオリティを実現 | エンタープライズ | マイコミジャーナル">マイコミジャーナルで紹介されていた</a>ので<a href="http://mozillaparser.sourceforge.net/" title="Mozilla Java Html Parser">Mozilla Java Html Parser</a>を触ってみたがうまくいかなかった。</p>
<p><a href="http://sourceforge.net/project/showfiles.php?group_id=186646" title="SourceForge.net: Files">Sourceforgeからダウンロード</a>してMozillaHtmlParser.jarおよびlibフォルダに含まれていたJARファイル群をEclipseの「外部アーカイブ」に追加。以下のような簡単なソースを書いた (ていうかMozillaHtmlParser.jarの中に入っていたcom.dappit.Dapper.parser.example.ParserExampleをさらに簡単にしたもの):</p>
<pre><code class="java">import java.io.File;

import org.w3c.dom.Document;

import com.dappit.Dapper.parser.EnviromentController;
import com.dappit.Dapper.parser.MozillaParser;

public class Test {
    public static void main(String[] args) throws Exception {
        File parserLibraryFile = new File("./native/bin/MozillaParser" + EnviromentController.getSharedLibraryExtension());
        String parserLibrary = parserLibraryFile.getAbsolutePath();
        System.out.println("Loading Parser Library :" + parserLibrary);
        final File mozillaDistBinDirectory = new File("mozilla.dist.bin."+EnviromentController.getOperatingSystemName());
        MozillaParser.init(parserLibrary,mozillaDistBinDirectory.getAbsolutePath());        
        
        try {
            MozillaParser parser = new MozillaParser();
            System.out.println("parsing...");
            
            String html = "&lt;html&gt;Test&lt;/html&gt;";
            Document document = parser.parse(html);
            System.out.println("Generated document :" + ((org.dom4j.Document)document).asXML());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("done...");
    }
}</code></pre>
<p>実行させると:</p>
<pre><samp>Operating system : Windows XP
Loading Parser Library :C:\Program Files\MozillaJavaHTMLParser\native\bin\MozillaParser.dll
parsing...
Cannot convert: null into a W3C DOM Node
done...
Initializing XPCOM from location : C:\Program Files\MozillaJavaHTMLParser\mozilla.dist.bin.win...
org.w3c.dom.DOMException: Not supported yet
    at org.dom4j.dom.DOMNodeHelper.notSupported(DOMNodeHelper.java:468)
    at org.dom4j.dom.DOMNodeHelper.asDOMNode(DOMNodeHelper.java:405)
    at org.dom4j.dom.DOMNodeHelper.getParentNode(DOMNodeHelper.java:79)
    at org.dom4j.dom.DOMElement.getParentNode(DOMElement.java:100)
    at com.dappit.Dapper.parser.DomDocumentBuilder.buildDocument(DomDocumentBuilder.java:109)
    at com.dappit.Dapper.parser.MozillaParser.parse(MozillaParser.java:84)
    at Test.main(Test.java:21)
</samp></pre>
<p>DomDocumentBuilder.javaの109行目付近を見ると:</p>
<pre><code class="java">            case ParserInstruction.CloseNode:
            {
                if (currentElement == null)
                {
                    System.err.println("Error : Close Node where no OpenNode was called. trying to fix...");
                    // this.dump();
                }
                else if (closeHtml)
                    currentElement = (Element) currentElement.getParentNode();</code></pre>
<p>変数currentElementはorg.w3c.Elementインターフェイスのインスタンスで、HTML要素の親ノードを取得しようとしたか、またはルートノードの親ノードを取得しようとしてNULLが出たのかなーと思ったが、まさかそんな基本的なところで躓くようなスクリプトが一般に公開されているとも思えないので私のやり方が悪いはず。でも見当がつかない。</p>
<p>Mozilla HTML Parserについて言及しているサイトを調べたが、<a href="http://labs.gmo.jp/blog/ku/2007/03/firefoxhtmlparserxpcomhtml1.html" title="FirefoxのhtmlparserをXPCOM経由で呼び出して壊れたHTMLを修復する - bits and bytes">bits and bytesの紹介記事</a> (直接Cから叩いている) と<a href="http://pc11.2ch.net/test/read.cgi/tech/1200151522/107" title="【初心者】Java質問･相談スレッド111【大歓迎】">プログラム技術板の質問スレ</a> (回答なし) くらいしか見当たらなかった。後者については、たしかに<a href="http://mozillaparser.sourceforge.net/quickstart.html" title="Mozilla Java Html Parser">Quick Start</a>には</p>
<pre><code class="java">Document domDocument = MozillaParser.getInstance().parse("&lt;html&gt;Hello world!&lt;/html&gt;");
MozillaParser.getInstance().stopRunning();</code></pre>
<p>なんて書いてあるからそうコーディングしてしまうけど、ちゃんとExampleファイルを見てみるとフツーにMozillaParserをnewしていたという<span class="face">^^</span> でもここを乗り越えると今私が嵌まっている罠が待っているわけで。誰かえらい人の降臨を待ちたいところ。</p>
<ins class="ps" datetime="2008-06-19T14:25:38+09:00" id="PS1213853138">
<p><a href="http://txqz.net/blog/2008/06/19/1424" title="Mozilla Java Html Parserが動いた">ちゃんとやったら動いた</a>。</p>
</ins>
			</div>
		</content>
		<category term="HTML"/>
		<category term="Java"/>
		<category term="パーサ"/>
		<trackback:ping>http://txqz.net/blog/2008/01/24/1559/tb</trackback:ping>
		<published>2008-01-24T15:59:09+09:00</published>
		<updated>2008-06-19T14:25:38+09:00</updated>
	</entry>
	<entry>
		<title>IEではてなスターが表示されなかった</title>
		<id>tag:txqz.net,2007-12-18:/blog/2007/12/18/1758</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/12/18/1758"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>はてなスターを設けたとあるHTML文書について、FirefoxやOperaでははてスタのアイコンが現れるのにIEだと現れないという問題が発生した。あれこれ試行錯誤してみたところ、どうやら<code class="html">&lt;textarea name="comment"&gt;</code>と<code class="html">&lt;dl id="comment"&gt;</code>が原因のようだった。IEはName属性とID属性を同じ名前空間で管理しているのかな。多分それが理由で、<code class="javascript">getElementById("comment")</code>を実行すると先に現れるTextarea要素にマッチしてしまっていた模様。</p>
<p>と思ったけど、もしかしたら、Name属性値とID属性値を同じ空間で管理するのはまっとうな挙動で、OperaやFirefoxは同じIDがあったら後に出てくる要素を優先しているだけなのかもしれない。これについては詳しく調査する必要があるような気もする、というかID属性の値とかもっと考えてコーディングしていれば今回のような問題は発生しない。</p>
			</div>
		</content>
		<category term="DOM"/>
		<category term="HTML"/>
		<category term="IE"/>
		<category term="JavaScript"/>
		<category term="はてなスター"/>
		<trackback:ping>http://txqz.net/blog/2007/12/18/1758/tb</trackback:ping>
		<published>2008-01-23T21:35:27+09:00</published>
		<updated>2008-01-23T21:46:45+09:00</updated>
	</entry>
	<entry>
		<title>ひどいHTMLをSAXパーサに読ませる</title>
		<id>tag:txqz.net,2007-08-10:/blog/2007/08/10/1200</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/08/10/1200"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://txqz.net/blog/2007/03/11/0711" title="なぜ人はこんなにひどいHTMLを書くのだろう">先日取り上げたexblogのひどいHTML</a>を、HTML向けSAXパーサに読ませるとどうなるかの実験。startElement()やendElement()がどうコールされるかによって、パーサごとの性格が現れる。</p>
<h3>コールバックメソッド</h3>
<p><var>level</var>はネストの深さを表すインスタンス変数。</p>
<pre><code class="java">public void startElement(String uri, String localName, String qName, Attributes attrs){
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.print("&lt;"+localName);
    for(int i = 0; i &lt; attrs.getLength(); i++)
        System.out.print(" "+attrs.getQName(i)+"=\""+attrs.getValue(i)+"\"");
    System.out.println("&gt;");
    level++;
}
public void endElement(String uri, String localName, String qName){
    level--;
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.println("&lt;/"+localName+"&gt;");
}
public void characters(char[] ch, int offset, int length){
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.println(StringUtils.substring(new String(ch,offset,length).trim(),0,20));
}</code></pre>
<h3>対象となるHTML (1)</h3>
<p>例によって見やすいように改行とインデントを加えています。</p>
<pre><code class="html">&lt;DIV CLASS=MNBODY&gt;
 &lt;TABLE WIDTH=150 BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER&gt;
  &lt;TR&gt;
   &lt;TD COLSPAN=3&gt;
    &lt;FORM NAME=finder METHOD=GET ACTION=http://www.exblog.jp/search/&gt;
     &lt;INPUT TYPE=HIDDEN NAME=blogid VALUE=970055211&gt;
   &lt;/TD&gt;
  &lt;/TR&gt;
  &lt;INPUT TYPE=HIDDEN NAME=t VALUE=0&gt;
  &lt;TR&gt;
   &lt;TD WIDTH=105 ALIGN=LEFT&gt;
    &lt;INPUT TYPE=TEXT NAME=q SIZE=15  CLASS=TXTFLD&gt;
   &lt;/TD&gt;
   &lt;TD WIDTH=5&gt;&lt;/TD&gt;
   &lt;TD WIDTH=40 ALIGN=LEFT&gt;
    &lt;INPUT TYPE=SUBMIT VALUE="検索" STYLE="WIDTH:40;HEIGHT:20;"&gt;
   &lt;/TD&gt;
  &lt;/TR&gt;
  &lt;TR&gt;
   &lt;TD COLSPAN=3&gt;
    &lt;/FORM&gt;
   &lt;/TD&gt;
  &lt;/TR&gt;
 &lt;/TABLE&gt;
&lt;/DIV&gt;</code></pre>
<h4><a href="http://people.apache.org/~andyc/neko/doc/html/" title="NekoHTML">CyberNeko HTML Parser</a>の場合</h4>
<pre><samp>&lt;DIV class="MNBODY"&gt;
 &lt;TABLE width="150" border="0" cellspacing="0" cellpadding="0" align="CENTER"&gt;
  &lt;TR&gt;
   &lt;TD colspan="3"&gt;
    &lt;FORM name="finder" method="GET" action="http://www.exblog.jp/search/"&gt;
     &lt;INPUT type="HIDDEN" name="blogid" value="970055211"&gt;
     &lt;/INPUT&gt;
    <em>&lt;/FORM&gt;</em>
   &lt;/TD&gt;
  &lt;/TR&gt;
  &lt;INPUT type="HIDDEN" name="t" value="0"&gt;
  &lt;/INPUT&gt;
  &lt;TR&gt;
   &lt;TD width="105" align="LEFT"&gt;
    &lt;INPUT type="TEXT" name="q" size="15" class="TXTFLD"&gt;
    &lt;/INPUT&gt;
   &lt;/TD&gt;
   
   &lt;TD width="5"&gt;
   &lt;/TD&gt;
   
   &lt;TD width="40" align="LEFT"&gt;
    &lt;INPUT type="SUBMIT" value="検索" style="WIDTH:40;HEIGHT:20;"&gt;
    &lt;/INPUT&gt;
   &lt;/TD&gt;
  &lt;/TR&gt;
  &lt;TR&gt;
   &lt;TD colspan="3"&gt;
   &lt;/TD&gt;
  &lt;/TR&gt;
 &lt;/TABLE&gt;
&lt;/DIV&gt;</samp></pre>
<p>td要素の終了を優先し、td要素内のform要素に終了タグを補完した。table直下にinputが残っている。</p>
<ins class="ps" datetime="2008-06-19T15:19:58+09:00" id="PS1213856398">
<p><a href="http://lobobrowser.org/cobra.jsp" title="Cobra: Pure Java HTML Renderer &amp; Parser (Open Source)">Cobra 0.98.2</a>でも同様の結果になった。</p>
</ins>
<h4><a href="http://home.ccil.org/~cowan/XML/tagsoup/" title="TagSoup home page">TagSoup</a>の場合</h4>
<p>Tag Soupの場合、URIを指定して直接読ませたりInputStreamを読ませたりすると日本語が文字化けするので、いったんStringに落としたものをSAXParserに読ませた。</p>
<pre><samp>&lt;div class="MNBODY"&gt;
 &lt;table align="CENTER" width="150" border="0" cellspacing="0" cellpadding="0"&gt;
  &lt;tr&gt;
   &lt;td colspan="3" rowspan="1"&gt;
    &lt;form enctype="application/x-www-form-urlencoded" method="GET" name="finder" action="http://www.exblog.jp/search/"&gt;
     &lt;input type="HIDDEN" name="blogid" value="970055211"&gt;
     &lt;/input&gt;
     <em>&lt;input type="HIDDEN" name="t" value="0"&gt;
     &lt;/input&gt;</em>
     &lt;tr&gt;
      &lt;td align="LEFT" colspan="1" rowspan="1" width="105"&gt;
       &lt;input type="TEXT" class="TXTFLD" name="q" size="15"&gt;
       &lt;/input&gt;
      &lt;/td&gt;
      &lt;td colspan="1" rowspan="1" width="5"&gt;
      &lt;/td&gt;
      &lt;td align="LEFT" colspan="1" rowspan="1" width="40"&gt;
       &lt;input type="SUBMIT" value="検索" style="WIDTH:40;HEIGHT:20;"&gt;
       &lt;/input&gt;
      &lt;/td&gt;
     &lt;/tr&gt;
     &lt;tr&gt;
      &lt;td colspan="3" rowspan="1"&gt;
      &lt;/td&gt;
     &lt;/tr&gt;
    &lt;/form&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
 &lt;/table&gt;
&lt;/div&gt;</samp></pre>
<p>form要素の連続性を優先したが、結果としてform要素の直下にtr要素が出現してしまった。</p>
<h4><a href="https://java.sun.com/j2se/1.5.0/ja/docs/ja/api/javax/swing/text/html/HTMLEditorKit.ParserCallback.html" title="HTMLEditorKit.ParserCallback (Java 2 Platform SE 5.0)">HTMLEditorKit.ParserCallback</a>の場合</h4>
<p>これはHTML3.2のパーサで、XHTMLを読ませると具合が悪い。でもついでなのでやってみた。ソースは:</p>
<pre><code class="java">public void handleStartTag(HTML.Tag tag, MutableAttributeSet attrs, int pos){
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.print("&lt;"+tag);
    Enumeration e = attrs.getAttributeNames();
    while(e.hasMoreElements()){
        Object o = e.nextElement();
        System.out.print(" "+o+"=\""+attrs.getAttribute(o)+"\"");
    }
    System.out.println("&gt;");
    level++;
}
public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attrs, int pos){
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.print("&lt;"+tag);
    Enumeration e = attrs.getAttributeNames();
    while(e.hasMoreElements()){
        Object o = e.nextElement();
        System.out.print(" "+o+"=\""+attrs.getAttribute(o)+"\"");
    }
    System.out.println(" /&gt;");
}
public void handleEndTag(HTML.Tag tag, int pos){
    level--;
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.println("&lt;/"+tag+"&gt;");
}
public void handleText(char[] data, int pos){
    for(int i = 0; i &lt; level; i++) System.out.print(" ");
    System.out.println(StringUtils.substring(new String(data).trim(),0,20));
}</code></pre>
<p>結果は</p>
<pre><samp>&lt;div class="mnbody"&gt;
 &lt;table cellspacing="0" align="center" border="0" width="150" cellpadding="0"&gt;
  &lt;tr&gt;
   &lt;td colspan="3"&gt;
    &lt;form name="finder" action="http://www.exblog.jp/search/" method="get"&gt;
     &lt;input value="970055211" name="blogid" type="hidden" /&gt;
    &lt;/form&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  <em>&lt;tr _implied_="true"&gt;
   &lt;td _implied_="true"&gt;</em>
    &lt;input value="0" name="t" type="hidden" /&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td align="left" width="105"&gt;
    &lt;input name="q" size="15" type="text" class="txtfld" /&gt;
   &lt;/td&gt;
   &lt;td width="5"&gt;
   &lt;/td&gt;
   &lt;td align="left" width="40"&gt;
    &lt;input style="WIDTH:40;HEIGHT:20;" value="検索" type="submit" /&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td colspan="3"&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
 &lt;/table&gt;
&lt;/div&gt;</samp></pre>
<p>table直下のinput要素をtrとtdでラップした。3つの中では結構成功に近い結果を出したのではないだろうか。ただ、このパーサはXHTMLにまったく対応していないのが残念。バージョンアップしないのかな。</p>
<ins class="ps" datetime="2008-06-19T13:56:31+09:00" id="PS1213851391">
<h4><a href="http://mozillaparser.sourceforge.net/" title="Mozilla Java Html Parser">Mozilla Java Html Parser</a>の場合</h4>
<p>これはSAXパーサではないので、DOMをプリントする必要があるが、その結果以下のようになった:</p>
<pre><samp>&lt;div class="MNBODY"&gt;
 &lt;table width="150" border="0" cellspacing="0" cellpadding="0" align="CENTER"&gt;
  &lt;tbody&gt;
   &lt;tr&gt;
    &lt;td colspan="3"&gt;
     &lt;form name="finder" method="GET" action="http://www.exblog.jp/search/"&gt;
      &lt;input type="HIDDEN" name="blogid" value="970055211"&gt;&lt;/input&gt;
     &lt;/form&gt;
    &lt;/td&gt;
    &lt;input type="HIDDEN" name="t" value="0"&gt;&lt;/input&gt;
    &lt;tr&gt;
     &lt;td width="105" align="LEFT"&gt;
      &lt;input type="TEXT" name="q" size="15" class="TXTFLD"&gt;&lt;/input&gt;
     &lt;/td&gt;
     &lt;td width="5"&gt;&lt;/td&gt;
     &lt;td width="40" align="LEFT"&gt;
      &lt;input type="SUBMIT" value="検索" style="WIDTH:40;HEIGHT:20;"&gt;&lt;/input&gt;
     &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
     &lt;td colspan="3"&gt;
     &lt;/td&gt;
    &lt;/tr&gt;
   &lt;/tr&gt;
  &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;</samp></pre>
<p>tbodyが補完されているのがいかにもMozillaのパーサという感じだが、tr直下にinputやtrが来てしまっている点が惜しい。とはいえ、これ以上どう修正すればいいのだろう。</p>
</ins>
<ins class="ps" datetime="2008-06-19T14:52:35+09:00" id="PS1213854755">
<h4><a href="http://htmlcleaner.sourceforge.net/" title="HtmlCleaner Project Home Page">HTMLCleaner</a>の場合</h4>
<pre><samp>&lt;div class="MNBODY"&gt;
 &lt;input name="t" type="HIDDEN" value="0"&gt;&lt;/input&gt;
 &lt;table align="CENTER" border="0" cellpadding="0" cellspacing="0" width="150"&gt;
  &lt;tbody&gt;
   &lt;tr&gt;
    &lt;td colspan="3"&gt;
     &lt;form action="http://www.exblog.jp/search/" method="GET" name="finder"&gt;
      &lt;input name="blogid" type="HIDDEN" value="970055211"&gt;&lt;/input&gt;
     &lt;/form&gt;
    &lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
    &lt;td align="LEFT" width="105"&gt;
     &lt;input class="TXTFLD" name="q" size="15" type="TEXT"&gt;&lt;/input&gt;
    &lt;/td&gt;
    &lt;td width="5"&gt;&lt;/td&gt;
    &lt;td align="LEFT" width="40"&gt;
     &lt;input style="WIDTH:40;HEIGHT:20;" type="SUBMIT" value="検索"&gt;&lt;/input&gt;
    &lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
    &lt;td colspan="3"&gt;&lt;/td&gt;
   &lt;/tr&gt;
  &lt;/tbody&gt;
 &lt;/table&gt;
&lt;/div&gt;</samp></pre>
<p>実はMozillaParserより頭が良かったりして。</p>
</ins>
<h3>対象となるHTML (2)</h3>
<p>もう1つ例を挙げる。p要素下にdiv要素があり、さらにその子供にp要素があるケース。具体的に言うと<a href="http://business.nikkeibp.co.jp/article/topics/20070806/131744/" title="自民大敗、本当の理由 (ニュースを斬る)：NBonline(日経ビジネス オンライン)">自民大敗、本当の理由 (ニュースを斬る)：NBonline(日経ビジネス オンライン)</a>。("(中略)"以外のコメントは元からあったもの)</p>
<pre><code class="html">&lt;td valign="top" rowspan="2" class="main_part"&gt;
 &lt;div id="articlecontent"&gt;
  &lt;h1 class="articleheader"&gt;自民大敗、本当の理由&lt;/h1&gt;
  &lt;h2 class="articleheader"&gt;小泉改革路線に逆行する安倍自民を国民が拒絶&lt;/h2&gt;
  &lt;ul class="articledata"&gt;
   &lt;li&gt;2007年8月7日　火曜日&lt;/li&gt;
   &lt;li&gt;&lt;a href="/bns/author.jsp?ID=131744&amp;OFFSET=0"&gt;谷川　博&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;div class="articlekeyword_wrapper"&gt;
   &lt;div class="articlekeyword"&gt;
    &lt;a href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%CF%C0%C5%C0"&gt;論点&lt;/a&gt;　
    &lt;a href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%BB%B2%B1%A1%C1%AA"&gt;参院選&lt;/a&gt;　
    &lt;a href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%B0%C2%C7%DC%C0%AF%B8%A2"&gt;安倍政権&lt;/a&gt;　
    &lt;a href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%BE%AE%C0%F4%B2%FE%B3%D7"&gt;小泉改革&lt;/a&gt;　
   &lt;/div&gt;
  &lt;/div&gt;
  &lt;p&gt;
   &lt;!--囲み --&gt;
   &lt;div class="kakomi"&gt;
    &lt;p&gt;参院選での自民党大敗については、既に年金問題、政治とカネ、閣僚の失言などいくつもの原因が挙げられている。だが、河野太郎・衆議院議員は根底にある本質的な敗因は、小泉改革の継承者であるはずの安倍政権と自民党が継承者としての責務を果たさず、むしろ逆行していることだと断ずる。「昔の自民党」に戻るなら、次の選挙も危うい。（聞き手は、日経ビジネス オンライン＝谷川 博）&lt;/p&gt;
   &lt;/div&gt;
   &lt;!--//囲み//  --&gt;
  &lt;/p&gt;
  &lt;p&gt;
   &lt;!--画像 --&gt;
   &lt;div class="figure" style="width:250px;"&gt;
    &lt;img src="250px1.jpg"&gt;
    &lt;p&gt;河野太郎・衆議院議員&lt;/p&gt;
   &lt;/div&gt;
   &lt;!--//画像// --&gt;
  &lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;NBO&lt;/strong&gt;　参院選は自民党の「歴史的大敗」となりました。年金の記録漏れ問題や「政治とカネ」の問題、閣僚の失言など様々な問題が重なり、自民党に激しい逆風が吹いた結果だと言われています。&lt;/p&gt;
  <em>&lt;!--(中略)--&gt;</em>
  &lt;div class="blocktitle_l"&gt;
   &lt;iframe width="528" height="100" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameborder="0" scrolling="no" bordercolor="#000000" src="http://bizad.nikkeibp.co.jp/NBP_AD/nbonline/ad/nbo_thisweek.shtml"&gt;
   &lt;/iframe&gt;
  &lt;/div&gt;
 &lt;/div&gt;
&lt;/td&gt;</code></pre>
<p>インタビュー本文のある段落をCSSセレクタ風に書くと、<code>td.main_part &gt; div#articlecontent &gt; p</code>となる。</p>
<h4><a href="http://people.apache.org/~andyc/neko/doc/html/" title="NekoHTML">CyberNeko HTML Parser</a>の場合</h4>
<p>長くなるので、一部改行とインデントを削除した。</p>
<pre><samp>&lt;TD valign="top" rowspan="2" class="main_part"&gt;
 &lt;DIV id="articlecontent"&gt;
  &lt;H1 class="articleheader"&gt;自民大敗、本当の理由&lt;/H1&gt;
  &lt;H2 class="articleheader"&gt;
   小泉改革路線に逆行する安倍自民を国民が拒
  &lt;/H2&gt;
  &lt;UL class="articledata"&gt;
   &lt;LI&gt;2007年8月7日　火曜日&lt;/LI&gt;
   &lt;LI&gt;&lt;A href="/bns/author.jsp?ID=131744&amp;OFFSET=0"&gt;谷川　博&lt;/A&gt;&lt;/LI&gt;
  &lt;/UL&gt;
  &lt;DIV class="articlekeyword_wrapper"&gt;
   &lt;DIV class="articlekeyword"&gt;
    &lt;A href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%CF%C0%C5%C0"&gt;論点&lt;/A&gt;　
    &lt;A href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%BB%B2%B1%A1%C1%AA"&gt;参院選&lt;/A&gt;　
    &lt;A href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%B0%C2%C7%DC%C0%AF%B8%A2"&gt;安倍政権&lt;/A&gt;　
    &lt;A href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%BE%AE%C0%F4%B2%FE%B3%D7"&gt;小泉改革&lt;/A&gt;　
   &lt;/DIV&gt;
  &lt;/DIV&gt;
  <em>&lt;P&gt;
   &lt;DIV class="kakomi"&gt;
   &lt;/DIV&gt;
  &lt;/P&gt;
  &lt;P&gt;
   参院選での自民党大敗については、既に年金
   の選挙も危うい。（聞き手は、日経ビジネス
  &lt;/P&gt;</em>
 &lt;/DIV&gt;
 &lt;P&gt;
 &lt;/P&gt;
 &lt;P&gt;
  &lt;DIV class="figure" style="width:250px;"&gt;
   &lt;IMG src="250px1.jpg"&gt;
   &lt;/IMG&gt;
  &lt;/DIV&gt;
 &lt;/P&gt;
 &lt;P&gt;河野太郎・衆議院議員&lt;/P&gt;
 &lt;P&gt;
 &lt;/P&gt;
 &lt;P&gt;
  &lt;STRONG&gt;NBO&lt;/STRONG&gt;　参院選は自民党の「歴史的大敗」となりま
 &lt;/P&gt;
 &lt;!--中略--&gt;
 &lt;DIV class="blocktitle_l"&gt;
  &lt;IFRAME width="528" height="100" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameborder="0" scrolling="no" bordercolor="#000000" src="http://bizad.nikkeibp.co.jp/NBP_AD/nbonline/ad/nbo_thisweek.shtml"&gt;
  &lt;/IFRAME&gt;
 &lt;/DIV&gt;
&lt;/TD&gt;</samp></pre>
<p><q cite="http://business.nikkeibp.co.jp/article/topics/20070806/131744/" title="自民大敗、本当の理由 (ニュースを斬る)：NBonline(日経ビジネス オンライン)">参院選での自民党大敗</q>～の段落が<code>div.kakomi</code>から外に出てしまっている。そのあおりで、インタビュー本文のある段落の場所も<code>td.main_part &gt; p</code>となってしまった。なので、NekoHTMLのDOMパーサで<code>div.kakomi</code>や<code>div#articlecontent</code>を取得しようと思ってもうまくいかない。前者は空白のみで、後者は<q cite="http://business.nikkeibp.co.jp/article/topics/20070806/131744/" title="自民大敗、本当の理由 (ニュースを斬る)：NBonline(日経ビジネス オンライン)">自民大敗、本当の理由</q>から<q cite="http://business.nikkeibp.co.jp/article/topics/20070806/131744/" title="自民大敗、本当の理由 (ニュースを斬る)：NBonline(日経ビジネス オンライン)">（聞き手は、日経ビジネス オンライン＝谷川 博）</q>までしか取得できない。</p>
<h4><a href="http://home.ccil.org/~cowan/XML/tagsoup/" title="TagSoup home page">TagSoup</a>の場合</h4>
<p>上と同じように、一部改行と空白を削除したところがある。</p>
<pre><samp>&lt;td colspan="1" rowspan="2" valign="top" class="main_part"&gt;
 &lt;div id="articlecontent"&gt;
  &lt;h1 class="articleheader"&gt;自民大敗、本当の理由&lt;/h1&gt;
  &lt;h2 class="articleheader"&gt;
    小泉改革路線に逆行する安倍自民を国民が拒&lt;/h2&gt;
  &lt;ul class="articledata"&gt;
   &lt;li&gt;2007年8月7日　火曜日&lt;/li&gt;
   &lt;li&gt;
    &lt;a shape="rect" href="/bns/author.jsp?ID=131744&amp;OFFSET=0"&gt;谷川　博&lt;/a&gt;
   &lt;/li&gt;
  &lt;/ul&gt;
  &lt;div class="articlekeyword_wrapper"&gt;
   &lt;div class="articlekeyword"&gt;
    &lt;a shape="rect" href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%CF%C0%C5%C0"&gt;論点&lt;/a&gt;　
    &lt;a shape="rect" href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%BB%B2%B1%A1%C1%AA"&gt;参院選&lt;/a&gt;　
    &lt;a shape="rect" href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%B0%C2%C7%DC%C0%AF%B8%A2"&gt;安倍政権&lt;/a&gt;　
    &lt;a shape="rect" href="/bns/bnsearch.jsp?BID=1006&amp;OFFSET=0&amp;SEARCH_TEXT=%BE%AE%C0%F4%B2%FE%B3%D7"&gt;小泉改革&lt;/a&gt;　
   &lt;/div&gt;
  &lt;/div&gt;
  <em>&lt;p&gt;&lt;/p&gt;
  &lt;div class="kakomi"&gt;
   &lt;p&gt;
    参院選での自民党大敗については、既に年金
   &lt;/p&gt;
  &lt;/div&gt;
  &lt;p&gt;&lt;/p&gt;</em>
  &lt;div class="figure" style="width:250px;"&gt;
   &lt;img src="250px1.jpg"&gt;&lt;/img&gt;
   &lt;p&gt;河野太郎・衆議院議員&lt;/p&gt;
  &lt;/div&gt;
  &lt;p&gt;
   &lt;strong&gt;NBO&lt;/strong&gt;　参院選は自民党の「歴史的大敗」となりま
  &lt;/p&gt;
  &lt;!--中略--&gt;
  &lt;div class="blocktitle_l"&gt;
   &lt;iframe frameborder="0" scrolling="no" width="528" height="100" marginwidth="0" marginheight="0" hspace="0" vspace="0" bordercolor="#000000" src="http://bizad.nikkeibp.co.jp/NBP_AD/nbonline/ad/nbo_thisweek.shtml"&gt;
   &lt;/iframe&gt;
  &lt;/div&gt;
 &lt;/div&gt;
&lt;/td&gt;</samp></pre>
<p>こちらは、p要素下にdiv要素が来ることを防いだ。<code>div#articlecontent</code>がちゃんと直親td要素の終了直前まで続いているので、<code class="xpath">//div[@id='articlecontent']</code>というXPATH式で本文部分全体を取得できる。</p>
<h4><a href="https://java.sun.com/j2se/1.5.0/ja/docs/ja/api/javax/swing/text/html/HTMLEditorKit.ParserCallback.html" title="HTMLEditorKit.ParserCallback (Java 2 Platform SE 5.0)">HTMLEditorKit.ParserCallback</a>の場合</h4>
<p>このパーサは想定外の要素に弱いみたいで、処理中にArrayIndexOutOfBoundsExceptionが発生した。原因は84行目をはじめ随所に現れるcomment要素で、これらを削除したところ例外を出さずに処理を終えることができ、TagSoupと似た結果になった。</p>
<p>これら結果を見る限り、HTMLの文法を最も理解しているのはHTMLEditorKit.ParserCallbackのように思える。しかし、このパーサはSAX標準のインタフェースに則っておらず、イリーガルな要素が現れると例外が出てしまうというのが痛い。HTML4.01/XHTML1.0に準じるようなバージョンアップをしてくれないかなー。TagSoupは<a href="http://www-06.ibm.com/jp/developerworks/xml/060602/j_x-tiptagsoup.shtml" title="IBM dW : XML : ヒント: ひどいHTMLをTagSoupで修正する - Japan">評判</a>どおり中々優秀だが、InputStreamの日本語を正しく理解してくれないのが難点。<a href="http://homepage.mac.com/yuji_okamura/DotMac/t/archives/2005/12/entry_75.html" title="Thingamablog メモ : tagsoup カスタム版">日本語の問題を解決したカスタム版</a>があるっぽい? でもこれは実体参照されてしまう問題を解決するためのものだから違うか。1回Stringにすれば問題ないので使えないわけではない。</p>
<h4><a href="http://sourceforge.net/projects/shanidom/" title="SourceForge.net: ShaniXmlParser">ShaniXmlParser</a>の場合</h4>
<p>ShaniXMLParserは、HTMLのエラー訂正をDOM層でやっているぽい (DocumentBuilderFactoryでDTDを読むかどうかの指定ができるが、SAXParserFactoryにはない) のでちょっと特殊 (<code class="html">&lt;img ～ &gt;</code>となっているとendElement()がコールされない。<code class="html">&lt;img ～ /&gt;</code>だとコールされる) だ。</p>
<ins class="ps" datetime="2008-06-19T14:01:38+09:00" id="PS1213851698">
<h4><a href="http://mozillaparser.sourceforge.net/" title="Mozilla Java Html Parser">Mozilla Java Html Parser</a>の場合</h4>
<p>空のp要素ノードが2つ多く生成されたことを除けば、TagSoupの出力結果と同じになった。</p>
</ins>
<p>にしてもブラウザ付属のDOMパーサは凄いなあと思う。MozillaのDOMパーサってどうなっているんだろう。</p>
			</div>
		</content>
		<category term="HTML"/>
		<category term="Java"/>
		<category term="NekoHTML"/>
		<category term="SAX"/>
		<category term="TagSoup"/>
		<category term="ひどいHTML"/>
		<category term="パーサ"/>
		<category term="ライブラリ"/>
		<trackback:ping>http://txqz.net/blog/2007/08/10/1200/tb</trackback:ping>
		<published>2007-08-10T12:00:15+09:00</published>
		<updated>2008-09-19T14:17:47+09:00</updated>
	</entry>
	<entry>
		<title>HTML勉強会で何を教えるべき?</title>
		<id>tag:txqz.net,2007-08-08:/blog/2007/08/08/2140</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/08/08/2140"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>ということで今週は勉強会週間ということで、前々からネタとして上がっていた「HTMLと私」(元ネタは<a href="http://mizuno-labo.cs.inf.shizuoka.ac.jp/mizunolabo/rope_group_92CA8FED_title_908596EC928991A58BB38EF6.html" title="水野研究室:通常:水野忠則教授">水野先生</a>のシラバスにあった「OSと私」というフレーズ) を話すことになった。さすがにそれはきついので、とりあえず普通のHTML勉強会を開いた。</p>
<p>さて、HTML勉強会では何から教えるべきなのだろうか。<a href="http://www.asahi-net.or.jp/~jy3k-sm/css1/index.html" title="using CSS1 with HTML">すみけんさんの本</a>みたいに「ももたろう」のマークアップをしながら必要な要素について解説していくのがよいだろうか。それともHTMLの要素群を&lt;html&gt;から順番に解説していくのがよいだろうか。そもそも教えるべきはHTML3.2なのかHTML4.01なのかXHTML1.0なのかXHTML1.1なのか、はたまたISO-HTMLなのか。HTML4.01やXHTML1.0だとしたらTransitionalな要素や属性に触れるべきか――</p>
<p>みんなに何が知りたいか訊いて、あと後輩が書いたHTMLを見て思ったこともあったので、とりあえず文法から話すことにした。件のHTMLはliがbody直下に出ていたり、h3がdl直下にあったりして、とりあえずここら辺を重点的に話した方が良いだろうと思った。HTMLの基本的なところはみんな1年生の講義で習っているはずだしね。この世にはブロック要素とインライン要素がありましてね、という話をしたら、まずブロック要素とかインライン要素とは何だということになった。XTHML1.0 StrictのDTDファイルをプロジェクタに大写ししながら説明を始めた。文字ばかりのDTDファイルが出てきた時点でｄｎｂｋか? サーセン</p>
<p>テキトーに解説すると、ブロック要素は段落。矩形。インライン要素はその一部。下線。で、ブロック要素には、(1)ブロック要素しか子供にしないのと(2)インライン要素しか子供にしないのと、(3)特別な要素しか子供にしないのと、(4)ほとんど全ての要素を子供にできるものがあって、(1)はbodyやnoscriptやblockquoteで、(2)はh1とかpとかaddressで、(3)はulとかtableとかで、(4)はliやdd (どちらも%block;には含まれていないのでブロック要素として教えるのは不適当か?) やdivがあると。ここに挙げたのは「引用段落」だとか「大見出し」だとか「テーブル」だとかみたいな文章を構成する大きな枠組みで、これがブロック要素。インライン要素というのは、強調語句をあらわすemや上付き文字をあらわすsup、プログラムコードの断片をあらわすcodeなどのように、段落の中の一部分を指定するもの。……ってこんな説明で良いのだろうか。確かに、人に教えることは自分の無知を確認することだと思った。</p>
<p>ついで質問があったのが、divとかspanとかって何だという話。divは汎用ブロック要素でspanは汎用インライン要素。たとえば、この部分は日付なんだーというのをマークアップしたいときに、date要素なんてものはないので、span要素を使う。で、class属性に"date"とでも書いておく。こうすれば、「ここは日付なんだな」というのが分かる。ただし、パーサから見れば、spanはspanでしかない。パーサはvarが変数でdfnが定義語でsampが表示結果であるというHTMLで定義されている語彙は理解するが、spanやdivにどんなclassやidが指定されていても、パーサは<em>意味</em>を理解しない。ここら辺に約束を定めてそれに従うパーサ間で意味を共有しようというのが、今流行のMicroformatsですな。XHTMLみたいなXML言語だと話がもう1段上がって、XML的にはpだろうがqだろうがパーサはその意味を感知しないけど、XHTMLの名前空間下においては、pは段落でqは引用語句だという意味を持つ。だからこそ、「引用語句とその引用元を抜き出して一覧にしよう」だとか、「見出しを抜き出して目次を自動生成しよう」だとか「定義語を抜き出して索引を作ろう」だとかを自動にできることになっている。</p>
<p>いったい私は何をしゃべっているんだと思いつつ今度はCSS編。HTMLだと論理的な面からブロックだのインラインだの言ってたけど、CSSの場合はまさにレイアウト的な面からの話になる。ブロック要素は前後に改行が入って、一まとまりごとにpaddingやmarginが計算される。インラインの場合は……なんて、displayの値をいじったときにborderがどう表示されるか観察すれば分かる話か。あと<a href="https://addons.mozilla.org/ja/firefox/addon/1843" title="Firebug :: Firefox Add-ons">Firebug</a>のinspectモードが大活躍。</p>
<p>あとは、よく使うプロパティの説明をした。text-alignプロパティは段落内の文書をどちらに寄せるかを指定するので、display:inlineな要素には指定できない。逆にvertical-alignプロパティは、段落内にある高さがさまざまなインライン部品をどこ基準で揃えるかを指定するのでdisplay:inlineな要素に指定する。あとはline-heightプロパティの値に単位を指定するのと指定しないのとでどう表示が違うかとか。</p>
<p>みんなの関心が高いのは段組だったので、次に段組の定石について。floatを使うのとpositionを使うのと、あとinline-blockを使う手があるが最後のは現状Opera専用なので無視。floatを使う場合は、floatさせるブロックにwidthを指定する必要がある点に注意。ただ、メジャーなブラウザはwidthなしfloatを実にうまい感じにレイアウトしてくれるのが何とも。右カラムに画像があったりして右カラムの幅を一定値にしたいとなったら、HTML上先に右カラムを書いて、その右カラムにwidthをつけてfloat、左カラムは右width分プラスアルファのmarginを着けるのがセオリー。左カラムをHTML上先に書きたい場合は? どっかで妥協するしかない。</p>
<p>positionを使うのがその妥協のひとつ。position:absoluteなブロックにleft値とright値を指定すれば、可変長浮きブロックのできあがり。左カラムのrightが10%なら右カラムの左マージンを90%にすればいいし、左カラムのrightが10emなら右カラムはwidthを10emにしてfloat:rightさせればOK。ただ、私としてはあんまりpositionを使いたくないけど別にこだわりません。うまく使えばレイアウト崩壊も防げましょう。私があまり使いたくないのは、Googleキャッシュとかで見られると上方向にレイアウトが崩れるからだけど、そんなに重視すべき理由ではない。</p>
<p>で、結局何を話せばよかったのだろうか。なんか、教材代わりに使える良質丁寧なHTML/CSSサイトがあると良いな。ただのリファレンスじゃなくて体系立てて1から読めるようなやつ。探すか。</p>
			</div>
		</content>
		<category term="CSS"/>
		<category term="HTML"/>
		<category term="ポリタンク"/>
		<category term="勉強会"/>
		<trackback:ping>http://txqz.net/blog/2007/08/08/2140/tb</trackback:ping>
		<published>2007-08-22T15:28:06+09:00</published>
		<updated>2007-08-22T15:30:48+09:00</updated>
	</entry>
	<entry>
		<title>はてダに&lt;!--～--&gt;を書くと記事別ページでその部分が消える</title>
		<id>tag:txqz.net,2007-08-02:/blog/2007/08/02/2024</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/08/02/2024"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://d.hatena.ne.jp/Kishi/20070802/1186023181" title="public static void main - Google Adsenseの導入">public static void main</a>を読んでいたら</p>
<blockquote cite="http://d.hatena.ne.jp/Kishi/20070802/1186023181" title="public static void main - Google Adsenseの導入">
<pre><code class="html">&lt;script type=&quot;text/javascript&quot;&gt;
&lt;/script&gt;</code></pre>
<p>に</p>
<pre><code class="html">&lt;script type=&quot;text/javascript&quot;&gt;
&lt;/script&gt;</code></pre>
<p>と追加したら日本の広告が出るようになりました。 ｢AdSense コードを変更しないでください。｣って書いてあったのですが、XHTML的には</p>
<pre><code class="html">&lt;script&gt;
&lt;--
.
.
.
--&gt;
&lt;/script&gt;</code></pre>
<p>のような書き方はできないので、外部ファイルで参照できるようにしてもらえるとありがたいです。</p>
</blockquote>
<p>とあって、beforeとafterで何も変わっていないじゃんと本人に訊いたら本人も驚いていた。</p>
<p>トップページの最近の日記を見ると</p>
<blockquote cite="http://d.hatena.ne.jp/Kishi/" title="public static void main">
<pre><code class="html">&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;hogehoge&quot;;
google_ad_width = 728;
.
.
.
--&gt;
&lt;/script&gt;</code></pre>
<p>に</p>
<pre><code class="html">&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_language = 'ja';
google_ad_client = &quot;hogehoge&quot;;
google_ad_width = 728;
.
.
.
--&gt;
&lt;/script&gt;</code></pre>
<p>と追加したら日本の広告が出るようになりました。</p>
</blockquote>
<p>と、本人の意図した表示結果が出てきた。トップページのと個別ページのとで記法の解釈方法が違うのか? 最後のコード片だけちゃんと見えていたのは、"&lt;"と"--"の間に"!"がなかったからで、追加したらちゃんと(?)このコード片も個別ページのから消えた。</p>
			</div>
		</content>
		<category term="&lt;!----&gt;"/>
		<category term="HTML"/>
		<category term="はてなダイアリー"/>
		<category term="不具合"/>
		<trackback:ping>http://txqz.net/blog/2007/08/02/2024/tb</trackback:ping>
		<published>2007-08-02T20:24:42+09:00</published>
		<updated>2007-08-02T20:24:42+09:00</updated>
	</entry>
	<entry>
		<title>OperaのXMLパーサってすごかったのね</title>
		<id>tag:txqz.net,2007-07-07:/blog/2007/07/07/2106</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/07/07/2106"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>OperaにXMLファイルを読ませるとベタテキストが出てくる。フィードだと「新規購読」というダイアログが出るけれども、画面に表示されるのは容赦ないベタテキストだ。IEやFirefoxにスタイル情報のないXMLを渡せばドキュメントツリーを表示してくれるのと対照的で、どうもOperaはXMLにやる気がないのかと勝手に思っていた。</p>
<p>だが、整形式でないXMLを投げた場合、Operaのエラー表示が圧倒的に見やすいことに最近気づいた。たとえば、以下のようなXMLをブラウザに表示させてみる:</p>
<pre><code class="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;root&gt;
    &lt;hoge&gt;あああ&lt;/hoge&gt;
    &lt;hoge&gt;いいい
    &lt;hoge&gt;ううう&lt;/hoge&gt;
&lt;/root&gt;</code></pre>
<p>Firefoxだと:</p>
<div><img src="/figure/2007/07/07/firefox" alt="" /></div>
<pre><samp>XML パースエラー: タグの対応が間違っています。終了タグが必要です: &lt;/hoge&gt;
URL: file:///D:/test.xml
行番号: 6, 列番号: 3:

&lt;/root&gt;
--^</samp></pre>
<p>IEだと:</p>
<div><img src="/figure/2007/07/07/ie" alt="" /></div>
<pre><samp>XML ページを表示できません 
XSL スタイル シートを使用した XML 入力は表示できません。エラーを訂正してください。 [更新] ボタンをクリックするか、または後でやり直してください。 


--------------------------------------------------------------------------------

終了タグ 'root' が開始タグ 'hoge' と一致していません。リソース 'file:///D:/test.xml' の実行エラーです。ライン 6、位置 3

&lt;/root&gt;
--^</samp></pre>
<p>どちらも、6行目に問題があると言ってくる。だが、では<code class="xml">&lt;/hoge&gt;</code>を追加しようとしても、いったい何行目のhoge要素が閉じられていないのか分からないのだ。でもOperaは違う。</p>
<div><img src="/figure/2007/07/07/opera" alt="" /></div>
<pre><samp>エラー!
XML の解析に失敗しました

XML の解析に失敗しました: 構文エラー (行: 6, 文字: 0)

HTML ドキュメントとして再解析する
エラーmismatched end-tag
仕様http://www.w3.org/TR/REC-xml/
  1: &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  2: &lt;root&gt;
  3:     &lt;hoge&gt;あああ&lt;/hoge&gt;
  4:     <em>&lt;hoge&gt;</em>いいい
  5:     &lt;hoge&gt;ううう&lt;/hoge&gt;
  6: <em>&lt;/root&gt;</em></samp></pre>
<p>と、何行目のhoge要素のせいで6行目のエラーが発生したのかを強調表示で教えてくれる。これは6行しかないから目視で分かるけど、インデントなしで千何行もあったら人間の仕事じゃなくなるわけで、Operaのこの挙動は大変ありがたい。</p>
<p>Xercesも</p>
<pre><samp>[Fatal Error] :6:3: The element type "hoge" must be terminated by the matching end-tag "&lt;/hoge&gt;".</samp></pre>
<p>にとどまる。何行目のせいで整形式になっていないのかをちゃんと教えてくれるパーサってOperaくらいなのかなー。</p>
<p>ちなみに、不正なXMLにも対応しているパーサでこういうXMLを読ませると、以下のようになる。</p>
<p><a href="http://people.apache.org/~andyc/neko/doc/html/" title="NekoHTML">CyberNeko HTML Parser</a>の場合は (以下mainメソッドが例外をスローしてたりXMLをStringから読んでいたりしてやる気のないソースなので注意):</p>
<pre><code class="java">package net.txqz.test.xml;

import java.io.IOException;
import java.io.StringReader;

import org.cyberneko.html.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class NekoTest {
    public static void main(String[] args) throws SAXException, IOException {
        String xml = "&lt;?xml version='1.0' encoding='utf-8'?&gt;\n&lt;root&gt;\n&lt;hoge&gt;あああ&lt;/hoge&gt;\n&lt;hoge&gt;いいい\n&lt;hoge&gt;ううう&lt;/hoge&gt;\n&lt;/root&gt;";
        DOMParser parser = new DOMParser();
        parser.parse(new InputSource(new StringReader(xml)));
        Document document = parser.getDocument();
        NodeList nodes = document.getElementsByTagName("hoge");
        for(int i = 0; i &lt; nodes.getLength(); i++){
            Node node = nodes.item(i);
            System.out.println(node.getNodeName()+":"+node.getTextContent());
        }
    }
}</code></pre>
<p>出力結果は:</p>
<pre><samp>HOGE:あああ
HOGE:いいい
ううう

HOGE:ううう
</samp></pre>
<p><a href="http://sourceforge.net/projects/shanidom/" title="SourceForge.net: ShaniXmlParser">ShaniXmlParser</a>の場合は:</p>
<pre><code class="java">package net.txqz.test.xml;

import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class ShaniTest {
    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException{
        String xml = "&lt;?xml version='1.0' encoding='utf-8'?&gt;\n&lt;root&gt;\n&lt;hoge&gt;あああ&lt;/hoge&gt;\n&lt;hoge&gt;いいい\n&lt;hoge&gt;ううう&lt;/hoge&gt;\n&lt;/root&gt;";
        System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.allcolor.xml.parser.CDocumentBuilderFactory");
        System.setProperty("javax.xml.parsers.SAXParserFactory","org.allcolor.xml.parser.CSaxParserFactory");
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

        Document document = builder.parse(new InputSource(new StringReader(xml)));
        NodeList nodes = document.getElementsByTagName("hoge");
        for(int i = 0; i &lt; nodes.getLength(); i++){
            Node node = nodes.item(i);
            System.out.println(node.getNodeName()+":"+node.getTextContent());
        }
    }
}</code></pre>
<p>出力結果は:</p>
<pre><samp>hoge:あああ
hoge:いいい
ううう
hoge:ううう
</samp></pre>
<p><a href="http://jerichohtml.sourceforge.net/doc/index.html" title="Jericho HTML Parser">Jericho HTML Parser</a>の場合は:</p>
<pre><code class="java">package net.txqz.test.xml;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import au.id.jericho.lib.html.Element;
import au.id.jericho.lib.html.Source;

public class JerichoTest {
    public static void main(String[] args) throws IOException {
        String xml = "&lt;?xml version='1.0' encoding='utf-8'?&gt;\n&lt;root&gt;\n&lt;hoge&gt;あああ&lt;/hoge&gt;\n&lt;hoge&gt;いいい\n&lt;hoge&gt;ううう&lt;/hoge&gt;\n&lt;/root&gt;";
        Source src = new Source(new StringReader(xml));
        List&lt;Element&gt; list = src.findAllElements("hoge");
        for(Element element : list){
            System.out.println(element.getName()+":"+element.extractText());
        }
    }
}</code></pre>
<p>出力結果は:</p>
<pre><samp>hoge:あああ
hoge:
hoge:ううう
</samp></pre>
<p>Jericho HTML Parserは w3c DOMを使わずに独自の形式でHTMLやXMLをパースするのだけれども、不正なXMLもパースできるのがウリなのにこの方法で「いいい」を抽出できなかった。やりかたが悪い? いやまぁ整形式でないのが一番悪いのですが。ほかのパーサも「いいい」だけ抽出するのは不可能で、「いいい」と「ううう」がセットになる。それは、パーサがこの適当なXMLのDTDを知らないから当然の処理。HTMLで<code class="html">&lt;ul&gt;&lt;li&gt;あああ&lt;li&gt;いいい&lt;li&gt;ううう&lt;/ul&gt;</code>とかなっている場合は、HTMLパーサと名乗っている以上li要素の暗黙の終了タグをちゃんと補完してくれることでしょう。</p>
<p>あと、いま知ったのだけれども、XML宣言ってversionを必ず最初に指定しないといけないのね。encodingを先に指定したら<samp>[Fatal Error] :1:23: The version is required in the XML declaration.</samp>とXercesに怒られた。Xerces厳しすぎワロタと思ったら<cite><a href="http://www.w3.org/TR/REC-xml/" title="Extensible Markup Language (XML) 1.0 (Fourth Edition)">仕様</a></cite>に<q cite="http://www.w3.org/TR/REC-xml/" title="Extensible Markup Language (XML) 1.0 (Fourth Edition)">[23] XMLDecl ::= '&lt;?xml' VersionInfo EncodingDecl? SDDecl? S? '?&gt;'</q>って書いてあった。ふつうXMLの属性は登場順序に意味がないので、宣言もそうだと思い込んでいた。いまさらー。</p>
<ins class="ps" datetime="2007-07-13T16:58:36+09:00" id="PS20070713165836">
<blockquote title="livedoor クリップ - OperaのXMLパーサってすごかったのね" cite="http://clip.livedoor.com/page/http://txqz.net/blog/2007/07/07/2106">
<p>XMLはツリー表示されることを規定しないのでOperaはCSS初期値で表示してる(cf. <a href="http://kuruman.org/old_diary/200608#D19-01">http://kuruman.org/old_diary/200608#D19-01</a> )。パースエラーの開始箇所候補を挙げてくれるのはありがたいよね。</p>
</blockquote>
<p>なるほど。やっぱりはOperaすばらしいですね。</p>
</ins>
			</div>
		</content>
		<category term="Firefox"/>
		<category term="IE"/>
		<category term="Java"/>
		<category term="JerichoHTMLParser"/>
		<category term="NekoHTML"/>
		<category term="Opera"/>
		<category term="ShaniXMLParser"/>
		<category term="UA"/>
		<category term="XML"/>
		<category term="パーサ"/>
		<category term="ライブラリ"/>
		<trackback:ping>http://txqz.net/blog/2007/07/07/2106/tb</trackback:ping>
		<published>2007-07-07T21:06:00+09:00</published>
		<updated>2007-08-09T19:34:19+09:00</updated>
	</entry>
	<entry>
		<title>Google Japan Blogが句読点を文字参照している件</title>
		<id>tag:txqz.net,2007-07-02:/blog/2007/07/02/2100</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/07/02/2100"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://googlejapan.blogspot.com/2007/06/google-1.html" title="Google Japan Blog: Google エンジニア インタビューシリーズ 第 1 弾： 鵜飼文敏">Google エンジニア インタビュー</a>がはてブかどっかに上がっていて興味深く読んだのだが、なんで「？」とか「、」とか「。」とかを<del datetime="2007-07-03T06:11:13+09:00" cite="http://txqz.net/blog/2007/07/02/2100/reply#D548">実体参照</del><ins datetime="2007-07-03T06:11:13+09:00" cite="http://txqz.net/blog/2007/07/02/2100/reply#D548">文字参照</ins>しているのかよく分からん。システムの仕様なんだろうけど、なんでそんな仕様にする必要があるのかよく分からん。それでいて"&gt;"はそのまま書いてあるんだよなぁ。別に"&lt;"さえ実体参照しておけば"&gt;"は必ずしもエスケープしなくてもいいのかもしれないけど、なんか気持ち悪い。←なんという印象論。</p>
			</div>
		</content>
		<category term="HTML"/>
		<category term="ブログ"/>
		<category term="実体参照"/>
		<trackback:ping>http://txqz.net/blog/2007/07/02/2100/tb</trackback:ping>
		<published>2007-07-02T21:00:29+09:00</published>
		<updated>2007-07-04T18:16:45+09:00</updated>
	</entry>
	<entry>
		<title>BODY直下をDIVで揃えたい症候群</title>
		<id>tag:txqz.net,2007-06-12:/blog/2007/06/12/2159</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/06/12/2159"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<blockquote cite="http://3ping.org/2005/10/22/1556" title="Blogサイトで見かける変なHTML">
<p>上のソースでは、liのリスト項目をulで「順序の無い箇条書き」と明示しているのに、それを更にdiv要素としてマークアップしています。ほとんどの要素に対してid属性やclass属性は付けることが出来ますので、これなら直接ul要素にidを付加させましょう。</p>
</blockquote>
<p>確かにその通りだ。実際に私が今まで書いてきたHTML文書の中にもここで例示されているようなマークアップが何回か出てきていた。</p>
<p>なんとなく、BODYの直下にDIVとそれ以外が混ざるのが嫌だったんだと思った。もちろん文法上はそのような制限はない。ただ、なんとなくBODY直下にDIVが1つでも出てきたら全ての非DIV要素をDIVで包まないと落ち着かなかった。</p>
<p>例だと</p>
<pre><code class="html">&lt;div id="navi"&gt;
 &lt;ul&gt;
  &lt;li&gt;&lt;a&gt;About&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a&gt;Profile&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a&gt;Gallery&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a&gt;Links&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/div&gt;</code></pre>
<p>よりも</p>
<pre><code class="html">&lt;ul id="navi"&gt;
 &lt;li&gt;&lt;a&gt;About&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a&gt;Profile&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a&gt;Gallery&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>の方が良いですよねという話だけど、ナビゲーションリストに先駆けて見出しを起きたいなら、むしろ</p>
<pre><code class="html">&lt;div id="navi"&gt;
 &lt;h2&gt;ナビゲーション&lt;/h2&gt;
 &lt;ul&gt;
  &lt;li&gt;&lt;a&gt;About&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a&gt;Profile&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a&gt;Gallery&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a&gt;Links&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/div&gt;</code></pre>
<p>というマークアップが適切になるような気もする。結局はその場その場で適切に判断することになる。</p>
<p>あと、はてなダイアリーの<a href="http://hatenadiary.g.hatena.ne.jp/keyword/%e3%81%af%e3%81%a6%e3%81%aa%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e4%b8%80%e8%a6%a7" title="はてなモジュール一覧 - はてなダイアリーのヘルプ">はてなモジュール</a>を使うと</p>
<pre><code class="html">&lt;div class="hatena-module"&gt;
&lt;div class="hatena-moduletitle"&gt;最近のコメント&lt;/div&gt;
&lt;div class="hatena-modulebody"&gt;
&lt;ul class="hatena-recentcomment"&gt;
&lt;li&gt;&lt;a href="/denken/20070610/1181474055#c1182612946"&gt;2007-06-10&lt;/a&gt;&#160;な&lt;/li&gt;

&lt;li&gt;&lt;a href="/denken/20070401/1175391705#c1175397175"&gt;2007-04-01&lt;/a&gt;&#160;kiwofusi&lt;/li&gt;
&lt;li&gt;&lt;a href="/denken/20070329/1175125902#c1175158985"&gt;2007-03-29&lt;/a&gt;&#160;harukonbu&lt;/li&gt;
&lt;li&gt;&lt;a href="/denken/20070329/1175125902#c1175156359"&gt;2007-03-29&lt;/a&gt;&#160;umekoumeda&lt;/li&gt;
&lt;li&gt;&lt;a href="/denken/20070321/1174441534#c1174447026"&gt;2007-03-21&lt;/a&gt;&#160;umekoumeda&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>などのようなHTMLが出力されるが、これはDIV厨めいている。モジュールのスタイリングを一律にするためにhatena-modulebodyというクラスのDIV要素がUL要素をラップするようになっているが、厳密には不必要なDIV要素のはず。hatena-moduletitleについてはさらにひどいが、これはどの見出し要素を使うべきかは文章全体を見ないと決定できないために仕方なくやっているのかな。XHTML2.0のh要素が楽しみですね。</p>
			</div>
		</content>
		<category term="&lt;div&gt;"/>
		<category term="div厨"/>
		<category term="HTML"/>
		<category term="はてなダイアリー"/>
		<category term="マークアップ"/>
		<trackback:ping>http://txqz.net/blog/2007/06/12/2159/tb</trackback:ping>
		<published>2007-11-18T22:55:59+09:00</published>
		<updated>2007-11-18T22:57:09+09:00</updated>
	</entry>
	<entry>
		<title>XHTMLのContent-type</title>
		<id>tag:txqz.net,2007-06-07:/blog/2007/06/07/2032</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/06/07/2032"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>手動でマークアップするかぎり、やっぱりContent-typeにapplication/xhtml+xmlを指定するのはためらわれる。ぜったい間違えるし。<a href="http://txqz.net/blog/2007/04/17/2117#PS20070417235150" title="正しくHTMLを書こうと心がけている人に5の質問を">この間みたい</a>に。text/htmlなら間違えてもフールブルーフが働くかなーなんて。</p>
<p>RSSみたいに機械的にマークアップするようなリソースなら、プログラムが間違っていない限りほぼ完全に妥当なXMLを吐けるから、安心してapplication/rss+xmlとか名乗れるし、名乗らないといけない。一時期この日記は手書きに近い形でRSSを提供していたんだよねぇ。今じゃ考えられない。</p>
<p>そうなると、<a href="http://www.w3.org/TR/2002/NOTE-xhtml-media-types-20020801/xhtml-media-types.html" title="XHTML Media Types">Content-typeにtext/htmlを指定するのをオススメしていないXHTML1.1</a>は使うわけにいかず、XHTML1.0 Strictを採用することになるわけだ。ただ、XML応用言語で文書をマークアップする以上、やはりXMLツールで処理することを念頭においていることになる。それはXHTMLが整形式であることを前提とした考えだ。その一方、手書きしたXHTMLが間違っているかもしれないから、私はtext/htmlなXHTML1.0を書いている。まったく原理主義的でない。ていうか原理主義的だと疲れるからこれでいいと思った。最大公約数。</p>
			</div>
		</content>
		<category term="content-type"/>
		<category term="html"/>
		<category term="xhtml"/>
		<category term="xml"/>
		<category term="ウェブ標準"/>
		<trackback:ping>http://txqz.net/blog/2007/06/07/2032/tb</trackback:ping>
		<published>2007-06-07T20:32:11+09:00</published>
		<updated>2007-06-07T20:32:11+09:00</updated>
	</entry>
	<entry>
		<title>あんまりマークアップされないHTML要素</title>
		<id>tag:txqz.net,2007-05-13:/blog/2007/05/13/0109</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/05/13/0109"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>はてブに<a href="http://d.hatena.ne.jp/hmiyaza1/20070510/1178762985" title="Forgot the Milk. - Ajaxよりも先に覚えておくべき 忘れられた５つのHTMLタグ">Ajaxよりも先に覚えておくべき 忘れられた５つのHTMLタグ</a>という記事があがっていた。まぁソースコードを書かない人がvarだのcodeだのsampだのを覚えてもしょうがないけれども、dfn要素の明示はできる限りみんなやるべき。みなさんがどんなDTDに従ってHTMLまたはHTMLもどきを書いているかは分からないけど、少なくともhttp://www.w3.org/1999/xhtml名前空間において<a href="http://bakera.jp/ref/html/element/dfn" title="dfn要素@ばけらの HTML リファレンス(未完成)">dfn要素は被定義語をあらわす</a>というのが重要。SEOがどうとかそういうレベルじゃない。span要素にどんなクラス名をつけてもなんら意味がないけれど、dfn要素にはdefinitionという明白な意味がある。単に強調とかSEO対策とかしたいならem要素として明示すればいいんでないの? 効果があるかは知らないけど。</p>
<p>で、見出しをh1要素とかでマークアップしておけば目次を自動生成できたりするのが嬉しいわけだけれども、被定義語をdfn要素としてマークアップすると何が嬉しいか。まず索引を自動生成できるのが嬉しい。昔日記をXMLで書いていたときは<a href="http://web.archive.org/web/20040902112129/kabocha.org/wangando/diary/genre/index/dfn.html" title="湾岸日記からのDFN要素抜き出し">XSLTを使って索引を生成していた</a>。これはXSLTで書いたから、同じことをXHTMLでやっているブログがあればそこのデータもマージできる。はてダとかキーワードでつながるコミュニティは、辞書にある単語ならなんでもつながってしまうのが却ってわずらわしいかもしれない。被定義語でつながるコミュニティがあってもいいなと思った。謎。</p>
			</div>
		</content>
		<category term="&lt;dfn&gt;"/>
		<category term="html"/>
		<category term="SEO"/>
		<category term="自動生成"/>
		<category term="要素"/>
		<trackback:ping>http://txqz.net/blog/2007/05/13/0109/tb</trackback:ping>
		<published>2007-05-13T01:09:35+09:00</published>
		<updated>2007-11-27T14:21:32+09:00</updated>
	</entry>
	<entry>
		<title>正しくHTMLを書こうと心がけている人に5の質問を</title>
		<id>tag:txqz.net,2007-04-17:/blog/2007/04/17/2117</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/04/17/2117"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://www.rusica.net/note/2007/04/09/html5.html" title="正しくHTMLを書こうと心がけている人に5つの質問 : 雑記帳 : der Gegenwart">正しくHTMLを書こうと心がけている人に5つの質問</a>に回答。</p>
<dl class="qa">
<dt>HTML文書を制作する際に使用しているプログラムをお答えください。（Webプログラムも含む）</dt>
<dd><p>昔は<a href="http://homepage1.nifty.com/taka36/t3editor.htm" title="taka36's TTTEditor">TTTEditor</a>を使っていました。Ctrl+pで&lt;p&gt;&lt;/p&gt;が出るなどとショートカットを設定できるので、<a href="http://txqz.net/blog/2002/10/19/0004" title="タグ打ち">なんかいろいろ設定</a>してました。いまは、EmEditorとかの一般的なテキストエディタに書いてコピペしてます。</p></dd>
<dt>採用しているDTDとその理由をお答えください。</dt>
<dd><p>XHTML1.0 Strictにしています。前はXHTML1.1でした。ruby要素を使いたかったから。ただ、面倒であることや技術的な問題などでメディアタイプをapplication/xhtml+xmlにせずにtext/htmlにしてました。いまは、別にXHTML1.1なんて使わなくてもXHTMLであればよい (XML処理系でいろいろできる) のでXHTML1.0にしています。Strictなのは、別にTransitionalな要素や属性を使う必要に迫られていないからです。</p></dd>
<dt>何故正しくHTMLを書いているのですか？</dt>
<dd><p>正しく書かない理由がないからです。でも、たまに間違って正しくないHTMLになっちゃうこともあるよNE。</p></dd>
<dt>W3CとWHATWG、どちらに期待してますか？</dt>
<dd><p>後者のことをよく知らないので答えにくいですけど、別にW3Cに絶望していたりはしません。</p></dd>
<dt>あなたにとってHTMLとは何ですか？</dt>
<dd><p>よく普及したマークアップ言語。</p></dd>
</dl>
<p>というか、アレですね。質問ネタといえば<a href="/genre/100%E3%81%AE%E8%B3%AA%E5%95%8F" title="100の質問 # txqz (1/1)">100質のマークアップの話</a>が思い出されますね。あのとき私は</p>
<blockquote title="100の質問 # txqz (1/1)" cite="http://txqz.net/genre/100%E3%81%AE%E8%B3%AA%E5%95%8F">
<ol>
<li>これは1番目の質問から100番目の質問という<em>順番に意味があるリスト</em>なので、是非ol要素としておきたい</li>
<li>一つの質問に一つの回答が付くから定義リストであるような感じなので、是非dl要素としておきたい</li>
<li>すると、ol要素の子要素にdl要素が来て、<q cite="http://www.remus.dti.ne.jp/%7ea-satomi/nikki/2002/01c.html#d22n02">某方面およびその周辺</q>で良く見かけるマークアップとなる </li>
</ol>
</blockquote>
<p>なんて書きました。今は面倒なのでそのままdl-dt-ddです<span class="face">:-)</span>でも、dl要素にqa<ins datetime="2007-04-18T20:31:23+09:00">って値のclass</ins>属性をつけて、</p>
<pre><code class="css">dl.qa dt{
  display: list-item;
  list-style: decimal;
}</code></pre>
<p>なんてやろうかな。Firefoxだとみんな0になっちゃうみたいだけど。</p>
<ins class="ps" datetime="2007-04-17T23:51:50+09:00" id="PS20070417235150">
<p>IEだと1,3,5……と飛び飛びになってしまう件。んー。</p>
<blockquote title="はてなブックマーク - 徒栞 / 2007年04月17日" cite="http://b.hatena.ne.jp/kits/20070417#bookmark-4492683">
<p>[righthtml5q][notvalid]liの終了タグ抜け?</p>
</blockquote>
<p>直しました。</p>
</ins>
			</div>
		</content>
		<category term="100の質問"/>
		<category term="HTML"/>
		<category term="このサイト"/>
		<category term="反応"/>
		<trackback:ping>http://txqz.net/blog/2007/04/17/2117/tb</trackback:ping>
		<published>2007-04-17T21:17:42+09:00</published>
		<updated>2007-05-11T23:49:58+09:00</updated>
	</entry>
	<entry>
		<title>なぜ人はこんなにひどいHTMLを書くのだろう</title>
		<id>tag:txqz.net,2007-03-11:/blog/2007/03/11/0711</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/03/11/0711"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<pre><code class="html">&lt;DIV CLASS=MNBODYf&gt;
  &lt;TABLE WIDTH=150 BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER&gt;
    &lt;TR&gt;
      &lt;TD COLSPAN=3&gt;
        &lt;FORM NAME=finder METHOD=GET ACTION=http://www.exblog.jp/search/&gt;
          &lt;INPUT TYPE=HIDDEN NAME=blogid VALUE=1000036104&gt;
      &lt;/TD&gt;
    &lt;/TR&gt;
    &lt;INPUT TYPE=HIDDEN NAME=t VALUE=0&gt;
    &lt;TR&gt;
      &lt;TD WIDTH=105 ALIGN=LEFT&gt;
        &lt;INPUT TYPE=TEXT NAME=q SIZE=15  CLASS=TXTFLD&gt;
      &lt;/TD&gt;
      &lt;TD WIDTH=5&gt;&lt;/TD&gt;
      &lt;TD WIDTH=40 ALIGN=LEFT&gt;
        &lt;INPUT TYPE=SUBMIT VALUE="検索" STYLE="WIDTH:40;HEIGHT:20;"&gt;
      &lt;/TD&gt;
    &lt;/TR&gt;
    &lt;TR&gt;
      &lt;TD COLSPAN=3&gt;
        &lt;/FORM&gt;
      &lt;/TD&gt;
    &lt;/TR&gt;
  &lt;/TABLE&gt;
&lt;/DIV&gt;</code></pre>
<p>(見やすいように改行とインデントを加えました)</p>
<p>エキサイトブログはXHTMLを名乗っておきながら空要素を閉じないし、上に示したように整形式を書く気もさらさらないし、なんかクローラ対策かしらと勘ぐってしまいたいほどひどいHTMLになっている。なんなんだこれは。前に<a href="/blog/2006/09/27/2103" title="お尻空要素P">span要素のなかに&lt;p/&gt;&lt;p/&gt;というのが複数出てくるという二重三重に誤ったHTML</a>を見たことがあるが、何系の発想でこういうものが出てくるのか、本当に不思議でならない。平成の時代はあらゆる困難が科学の力で解決しているとされているが、魑魅魍魎はこんな形で私たちの前に姿を現しているのだ。</p>
			</div>
		</content>
		<category term="exblog"/>
		<category term="HTML"/>
		<category term="これはひどい"/>
		<category term="ひどいHTML"/>
		<trackback:ping>http://txqz.net/blog/2007/03/11/0711/tb</trackback:ping>
		<published>2007-03-11T07:11:00+09:00</published>
		<updated>2007-09-21T11:10:53+09:00</updated>
	</entry>
</feed>