SECTION 01 tidy 是什么
tidy 的中譯, 就是"整齊的", 而我們對(duì)于 HTML 這種純粹 tag 組合而成的語(yǔ)言, 常常會(huì)犯下一些失誤, 例如 <b> Hello <i> world , </b> Tidy </i> 這樣子 的順序錯(cuò)誤. 或者是通過網(wǎng)頁(yè)編輯器或轉(zhuǎn)換器編排十分凌亂, 根本無法閱讀 !!
因此, 當(dāng)我們?cè)陂_發(fā)程序, 尤其是網(wǎng)頁(yè)程序設(shè)計(jì)時(shí)候, 更需要有這種工具來輔助, 先有好的排版方式, 開發(fā)程序就能夠相對(duì)簡(jiǎn)單清楚, 更能夠提升自己的效率. 而且 tidy 可以幫忙檢查是否有 tag 的缺少或位置錯(cuò)誤, 可以讓我們馬上除錯(cuò), 不會(huì)在那邊計(jì)算有幾個(gè) <table> <tr> <td> </table> </tr> </td> 浪費(fèi)自己的時(shí)間 ~~
下載 jTidy: jtidy-04aug2000r7-dev.zip 這個(gè)版本非常的舊, 內(nèi)部存在著部分問題, 所以需要打些patch , PATCH 下載
SECTION 02 XHTML 是什么
XHTML 就是以 XML 技術(shù)為基礎(chǔ)的 HTML, 標(biāo)準(zhǔn)的格式是
- 他的根元素是 <html>
- 默認(rèn)的 namespace 是 "http://www.w3.org/1999/xhtml"
- 在根元素之前要有 DOCTYPE 的申明.
- 所有的 tag 都是小寫.
- 一定要有 <html>, <head>, <title> , 及<body> 這幾個(gè) Struture tags
- 屬性值需要用 "" 雙引號(hào)括起來
- 單一元素, 如 <br> 應(yīng)該修改為 <br/>
簡(jiǎn)單來說, XHTML 的出現(xiàn), 就是為了取代 HTML, 因?yàn)?HTML 難以成為數(shù)據(jù)交換的格式, 目前正在制定 XHTML 2.0 之中. 以下我列出 XHTML 1.0 的標(biāo)準(zhǔn)范例 :
<!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 轉(zhuǎn)成 XHTML
我們可以通過 jTidy 轉(zhuǎn)換舊有的 HTML 變成 XHTML, 無論將 xhtml 通過 iText 轉(zhuǎn)成 pdf 文件, 還是 cocoon 的 pipeline, 都比殘缺不能保證的 HTML 來得可靠, 下面這個(gè)范例, 就是將某個(gè) URL 的數(shù)據(jù)轉(zhuǎn)換成為 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]);
}
}
}
當(dāng)我們執(zhí)行 cmd> java -cp Tidy.jar TidyPage http://xxx.xxx.xxx.xxx/ 時(shí), 他就會(huì)顯示該網(wǎng)站標(biāo)準(zhǔn)的排版及 XHTML,
SECTION 04 通過 jTidy 轉(zhuǎn)換成為 XML
因?yàn)?Tidy.jar 內(nèi)部包有 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() );
}
}
}
只要執(zhí)行想要轉(zhuǎn)換的文件, 他將會(huì)將該文件輸出為 xml 格式, 並且排列整齊.
SECTION 05 結(jié)論
其實(shí), jtidy 的執(zhí)行方法有很多, 可以通過 cmd> java -jar Tidy.jar -help 來查看, 我們可以通過文件的配置來決定輸入輸出的格式, 有興趣請(qǐng)查看如何執(zhí)行 jTidy 的其他命令或配置, 可以直接參考 HTML Tidy How to run Tidy, 只是把 tidy (exe) 轉(zhuǎn)成 java -cp Tidy.jar 就可以了 ! 此外, Eclipse 及 jEdit 都有 jTidy support 的 plugins, 也有 jTidy ant Task , 大家可以下載來使用. |