自從javaei網(wǎng)站推出h2p以來,得到了很多人的支持和鼓勵(lì),也給出了很多寶貴意見,再次深表謝意。
這些意見主要是三個(gè)方面的問題。第一:為什么要生成pdf;第二:h2p文件分成兩個(gè),比較繁瑣,為什么不合成一個(gè);第三:h2p-tool由c#和java實(shí)現(xiàn),用起來不夠簡(jiǎn)單,需要進(jìn)一步完善。這三方面的意見提得非常好,在設(shè)計(jì)h2p之前,我其實(shí)是深思熟慮過的。
為什么要轉(zhuǎn)換成pdf?回答這個(gè)問題很簡(jiǎn)單也很難?我就簡(jiǎn)單的說一下,首先pdf已成為廣泛支持的具有豐富表現(xiàn)力的文檔格式;其次pdf是聚合、收藏網(wǎng)絡(luò)文章的最便利的文檔格式,因?yàn)槠鋸?qiáng)大的書簽功能和瘦小的體積;還有很多,不一一列舉了。說到底,h2p就是一個(gè)把網(wǎng)絡(luò)文章整理成pdf的一個(gè)完整的解決方案,有些網(wǎng)站也有制作電子書的功能,但是h2p是一個(gè)更加通用的解決方案。
關(guān)于h2p文件的問題,分成兩個(gè)文件來描述的確不方便,現(xiàn)在回想起來,當(dāng)時(shí)分成兩個(gè)文件是考慮的過多了,合并成一個(gè)文件迫在眉睫,而這是本文的主要內(nèi)容。
合并后的h2p文件其后綴為.h2p.xml,主要描述url的信息和url的層次結(jié)構(gòu),h2p-tool根據(jù)h2p文件生成有書簽的pdf文檔。合并后,對(duì)h2p文件的操作變得簡(jiǎn)單,還可以通過xsl直接展示url的層次結(jié)構(gòu),而且合作網(wǎng)站對(duì)h2p的支持也將變得簡(jiǎn)單。
經(jīng)過慎重考慮和仔細(xì)設(shè)計(jì),h2p文件的一個(gè)例子如下:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <?xml-stylesheet type="text/xsl" ?>
3 <!DOCTYPE book PUBLIC "-//JavaEI/JavaEI h2p Configuration DTD//CN" "http://www.javaei.com/dtd/javaei-h2p.dtd" >
4 <book name="我的PDF書">
5 <chapter name="163">
6 <chapter name="163新聞">
7 <href id="11111"><![CDATA[http://news.163.com]]></href>
8 </chapter>
9 <chapter name="163體育">
10 <href id="2222"><![CDATA[http://sports.163.com]]></href>
11 </chapter>
12 </chapter>
13 <chapter name="sohu">
14 <href id="333"><![CDATA[http://www.sohu.com]]></href>
15 <chapter name="sohu新聞">
16 <href id="444"><![CDATA[http://news.sohu.com]]></href>
17 </chapter>
18 </chapter>
19 </book>
20
對(duì)應(yīng)的dtd如下:
<!ELEMENT book (chapter+)>
<!ATTLIST book name CDATA #REQUIRED>
<!ELEMENT chapter (href?,chapter*)>
<!ATTLIST chapter name CDATA #REQUIRED>
<!ELEMENT href (#PCDATA)>
<!ATTLIST href id CDATA #REQUIRED>
利用xsl對(duì)該樣例文件的解析效果如圖:

層次結(jié)構(gòu)的深度是沒有限制的,h2p的xsl實(shí)現(xiàn)了對(duì)xml的解析和樹節(jié)點(diǎn)的構(gòu)造,如果對(duì)這方面的問題感興趣的可以參考我這個(gè)xsl。合作網(wǎng)站可以提供自己的xsl。Xsl解析xml生成樹的核心代碼如下:
1 <xsl:template match="http://chapter">
2 <xsl:for-each select=".">
3 <li>
4 <img class="nodeimg">
5 <xsl:choose>
6 <xsl:when test="./chapter">
7 <xsl:attribute name="src">http://www.javaei.com/res/images/closed.gif</xsl:attribute>
8 <xsl:attribute name="onclick">clicknode(this)</xsl:attribute>
9 </xsl:when>
10 <xsl:otherwise>
11 <xsl:attribute name="src">http://www.javaei.com/res/images/leaf.gif</xsl:attribute>
12 </xsl:otherwise>
13 </xsl:choose>
14 </img>
15 <xsl:choose>
16 <xsl:when test="./href">
17 <a>
18 <xsl:attribute name="href"><xsl:value-of select="./href" /></xsl:attribute>
19 <xsl:attribute name="target">right</xsl:attribute>
20 <xsl:attribute name="class">h2pnodestyle</xsl:attribute>
21 <xsl:value-of select="text()" /><xsl:value-of select="@name" />
22 </a>
23 </xsl:when>
24 <xsl:otherwise>
25 <xsl:value-of select="text()" /><xsl:value-of select="@name" />
26 </xsl:otherwise>
27 </xsl:choose>
28 <ul class="collapsed">
29 <xsl:apply-templates select="./chapter" />
30 </ul>
31 </li>
32 </xsl:for-each>
33 </xsl:template>
34
關(guān)鍵是這兩句:
<xsl:template match="http://chapter">
<xsl:apply-templates select="./chapter" />
這實(shí)際上形成了遞歸調(diào)用。
關(guān)于h2p-tool的問題,不得不說,這是個(gè)難題。要求根據(jù)url生成的pdf展現(xiàn)效果與瀏覽器里展現(xiàn)的效果一致,這無異于做一個(gè)瀏覽器,難度可想而知。在java領(lǐng)域,目前還沒找到一個(gè)可以用的解決方案,所以才不得不借助于別人的c#的組件。h2p-tool的完善工作將是以后的主要方向,大家如果有好的思路,請(qǐng)不吝賜教。
h2p詳細(xì)介紹
h2p文件示例