自從javaei網站推出h2p以來,得到了很多人的支持和鼓勵,也給出了很多寶貴意見,再次深表謝意。
這些意見主要是三個方面的問題。第一:為什么要生成pdf;第二:h2p文件分成兩個,比較繁瑣,為什么不合成一個;第三:h2p-tool由c#和java實現,用起來不夠簡單,需要進一步完善。這三方面的意見提得非常好,在設計h2p之前,我其實是深思熟慮過的。
為什么要轉換成pdf?回答這個問題很簡單也很難?我就簡單的說一下,首先pdf已成為廣泛支持的具有豐富表現力的文檔格式;其次pdf是聚合、收藏網絡文章的最便利的文檔格式,因為其強大的書簽功能和瘦小的體積;還有很多,不一一列舉了。說到底,h2p就是一個把網絡文章整理成pdf的一個完整的解決方案,有些網站也有制作電子書的功能,但是h2p是一個更加通用的解決方案。
關于h2p文件的問題,分成兩個文件來描述的確不方便,現在回想起來,當時分成兩個文件是考慮的過多了,合并成一個文件迫在眉睫,而這是本文的主要內容。
合并后的h2p文件其后綴為.h2p.xml,主要描述url的信息和url的層次結構,h2p-tool根據h2p文件生成有書簽的pdf文檔。合并后,對h2p文件的操作變得簡單,還可以通過xsl直接展示url的層次結構,而且合作網站對h2p的支持也將變得簡單。
經過慎重考慮和仔細設計,h2p文件的一個例子如下:
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
對應的dtd如下:
<!ATTLIST book name CDATA #REQUIRED>
<!ELEMENT chapter (href?,chapter*)>
<!ATTLIST chapter name CDATA #REQUIRED>
<!ELEMENT href (#PCDATA)>
<!ATTLIST href id CDATA #REQUIRED>
利用xsl對該樣例文件的解析效果如圖:
層次結構的深度是沒有限制的,h2p的xsl實現了對xml的解析和樹節點的構造,如果對這方面的問題感興趣的可以參考我這個xsl。合作網站可以提供自己的xsl。Xsl解析xml生成樹的核心代碼如下:
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
關鍵是這兩句:
<xsl:template match="http://chapter">
<xsl:apply-templates select="./chapter" />
這實際上形成了遞歸調用。
關于h2p-tool的問題,不得不說,這是個難題。要求根據url生成的pdf展現效果與瀏覽器里展現的效果一致,這無異于做一個瀏覽器,難度可想而知。在java領域,目前還沒找到一個可以用的解決方案,所以才不得不借助于別人的c#的組件。h2p-tool的完善工作將是以后的主要方向,大家如果有好的思路,請不吝賜教。