阳光不锈

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

作者:jini         来源:java 公开原始码报

申明:未经作者同意,谢绝转载 

Java 公开原始码报 (Java Opensource Newspaper) 现在已经有简体中文版, 如果习惯阅读简体中文的读者, 可以连结到 sentom.net 去阅读 ! 其他人如果需要转载到其他地方或翻译成为其他语言, 请来信告知 . 基本上只要不是作为营利用途, 我都会允以授权. 因为我希望, 能够將 Java Opensource 推广到更多的人群之中.

HTML tidy,
这是我最近才知道的一个东西, 因为刚好要把一些旧有的网页, 转换成为 XHTML, World Wide Web Consortium (W3C) 提出了一个 Opensource -- HTML tidy , 就是希望能够自动判断及修复容易写错的 HTML tags , 无论是 tag 的顺序, 还是 tag 是否有结尾等等这种疏失. 接着可以通过标准的转译方式, 将合法的 HTML 转换成为 XML 格式的文件.

不过, 大家看到的 tidy.sf.net , 是采用 C 语言开发的, 当然也有我们熟悉的 java 版本, 那就是本周主题 - jTidy.


增加 license 说明, 相关细节请参考 license 解说 [by Tempo]

ps:
如果要赞助本电子报发行, 请与我们联络->Johnny

本周主题 -- jTidy

SECTION 01 tidy 是什么

tidy 的中译, 就是"整齐的", 而我们对于 HTML 这种纯粹 tag 组合而成的语言, 常常会犯下一些失误, 例如 <b> Hello <i> world , </b> Tidy </i> 这样子 的顺序错误. 或者是通过网页编辑器或转换器编排十分凌乱, 根本无法阅读 !!


因此, 当我们在开发程序, 尤其是网页程序设计时候, 更需要有这种工具来辅助, 先有好的排版方式, 开发程序就能够相对简单清楚, 更能够提升自己的效率. 而且 tidy 可以帮忙检查是否有 tag 的缺少或位置错误, 可以让我们马上除错, 不会在那边计算有几个 <table> <tr> <td> </table> </tr> </td> 浪费自己的时间 ~~


下载 jTidy: jtidy-04aug2000r7-dev.zip
这个版本非常的旧, 內部存在着部分问题, 所以需要打些patch , PATCH 下载


SECTION 02 XHTML
是什么

XHTML 就是以 XML 技术为基础的 HTML, 标准的格式是

·                                 他的根元素是 <html>

·                                 默认的 namespace "http://www.w3.org/1999/xhtml"

·                                 在根元素之前要有 DOCTYPE 的申明.

·                                 所有的 tag 都是小写.

·                                 一定要有 <html>, <head>, <title> , <body> 这几个 Struture tags

·                                 属性值需要用 "" 双引号括起來

·                                 单一元素, <br> 应该修改为 <br/>

简单来说, XHTML 的出现, 就是为了取代 HTML, 因为 HTML 难以成为数据交换的格式, 目前正在制定 XHTML 2.0 之中. 以下我列出 XHTML 1.0 的标准范例 :

 
     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
     <title>test</title>
     </head>
     <body>
     hello world
     </body>
     </html>
                                
SECTION 03
利用 jTidy HTML 转成 XHTML

我们可以通过 jTidy 转换旧有的 HTML 变成 XHTML, 无论将 xhtml 通过 iText 转成 pdf 文件, 还是 cocoon pipeline, 都比残缺不能保证的 HTML 来得可靠, 下面这个范例, 就是将某个 URL 的数据转换成为 XHTML 的代码

 
      // core Java stuff.
      // author: Chris Raber
      import java.io.*;
      import java.text.*;
      import java.util.*;
      import java.net.*;
      // JTidy stuff.
      import org.w3c.tidy.Tidy;
      public class TidyPage {
      private static boolean DEBUG=false;
      public TidyPage(){
      }
      public void doTidy(String url)
      {
        URL u;
        BufferedInputStream sourceIn;
        ByteArrayOutputStream tidyOutStream;
        try{
             u = new URL(url);
             if(DEBUG){
                 System.out.println("URL protocol:"+u.getProtocol());
                 System.out.println("URL host:"+u.getHost());
                 System.out.println("URL path:"+u.getPath());
                 System.out.println("URL query:"+u.getQuery());
                 System.out.println("URL file:"+u.getFile());
                }
             Reader reader;
             sourceIn = new BufferedInputStream(u.openStream());
             tidyOutStream = new ByteArrayOutputStream();
             Tidy tidy = new Tidy();
             tidy.setQuiet(true);
             tidy.setShowWarnings(false);
             tidy.setIndentContent(true);
             tidy.setSmartIndent(true);
             tidy.setIndentAttributes(false);
             tidy.setWraplen(1024);
             // 输出为 XHTML 
             tidy.setXHTML(true);
             //tidy.setXmlOut(true);
             tidy.setErrout(new PrintWriter(System.out));
             tidy.parse(sourceIn, tidyOutStream);
              System.out.println(tidyOutStream.toString());
             } catch ( Exception ex ) {
                System.out.println( ex.toString());
                ex.printStackTrace();
                }
            }
     public static void main(String args[]){
         if(args.length != 1)
         System.out.println("Usage TidyPage url");
         else{
             TidyPage tp = new TidyPage();
             tp.doTidy(args[0]);
              }
        }
    }
                                

当我们执行 cmd> java -cp Tidy.jar TidyPage http://xxx.xxx.xxx.xxx/ , 他就会显示该网站标准的排版及 XHTML,


SECTION 04
通过 jTidy 转换成为 XML

因为 Tidy.jar 內部包有 dom sax, 以下就是 TestDOM Parser 范例

 
     import java.io.PrintWriter;
     import java.io.FileInputStream;
     import java.io.IOException;
     import org.w3c.dom.Attr;
     import org.w3c.dom.Document;
     import org.w3c.dom.NamedNodeMap;
     import org.w3c.dom.Node;
     import org.w3c.dom.NodeList;
     import org.w3c.tidy.Tidy;
     /**
     * A sample DOM writer. This sample program illustrates how to
     * traverse a DOM tree in order to print a document that is parsed.
     *
     */
     public class TestDOM {
       protected PrintWriter out;
       public TestDOM() {
          out = new PrintWriter(System.out);
        }
    /** Prints the specified node, recursively. */
    public void print(Node node) {
        if ( node == null ) {
            return;
        }
        int type = node.getNodeType();
        switch ( type ) {
          case Node.DOCUMENT_NODE:
          out.println("<?xml version=""1.0"" encoding=""UTF-8""?>");
          print(((Document)node).getDocumentElement());
          out.flush();
          break;
          case Node.ELEMENT_NODE:
          out.print('<');
          out.print(node.getNodeName());
          NamedNodeMap attrs = node.getAttributes();
          for ( int i = 0; i < attrs.getLength(); i++ ) {
            out.print(' ');
            out.print(attrs.item(i).getNodeName());
            out.print("=""");
            out.print(attrs.item(i).getNodeValue());
            out.print('"');
           }
         out.print('>');
         out.println(); // HACK
         NodeList children = node.getChildNodes();
         if ( children != null ) {
           int len = children.getLength();
           for ( int i = 0; i < len; i++ ) {
             print(children.item(i));
            }
       }
         break;
         case Node.TEXT_NODE:
         out.print(node.getNodeValue());
         break;
    }
      if ( type == Node.ELEMENT_NODE ) {
         out.print("</");
         out.print(node.getNodeName());
         out.print('>');
         out.println(); // HACK
      }
     out.flush();
   }
     public static void main(String args[]) {
       if ( args.length == 0 ) {
          System.exit(1);
       }
       System.err.println(args[0]);
       FileInputStream in;
       Tidy tidy = new Tidy();
       TestDOM t = new TestDOM();
       try {
          in = new FileInputStream(args[0]);
          tidy.setMakeClean(true);
          tidy.setXmlTags(true);
          t.print(tidy.parseDOM(in, null));
          }
        catch ( IOException e ) {
          System.err.println( e.toString() );
         }
      }
  }
                                

只要执行想要转换的文件, 他将会将该文件输出为 xml 格式, 並且排列整齐.


SECTION 05
结论

其实, jtidy 的执行方法有很多, 可以通过 cmd> java -jar Tidy.jar -help 来查看, 我们可以通过文件的配置来决定输入输出的格式, 有兴趣请查看如何执行 jTidy 的其他命令或配置, 可以直接参考 HTML Tidy How to run Tidy, 只是把 tidy (exe) 转成 java -cp Tidy.jar 就可以了 ! 此外, Eclipse jEdit 都有 jTidy support plugins, 也有 jTidy ant Task , 大家可以下载来使用.

posted on 2009-01-16 14:42  靳小透  阅读(463)  评论(0编辑  收藏  举报