`
xinklabi
  • 浏览: 1591793 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

Jtidy将html转换成xml(转)

 
阅读更多

转自:http://technicolor.iteye.com/blog/730337

 

最近在做一个项目,要把html转换为格式规范的xml(不受DTD约束),然后再用dom4j进行分析,于是就去找html to xml的工具。

发现有两款,一个是NekoHTML,一个是Jtidy。因为貌似Jtidy比较符合我的需求,于是我就下载了Jtidy(jtidy-r938,
2009-12-01,新版本的)。

JTidy是HTML Tidy(一个HTML语法检查器和优雅的打印编排工具)的Java移植,除了本身具有的清除HTML文件难看或错误内容的功能外,还提供了一个DOM接口,程序员可以将JTidy当作一个处理HTML文件的DOM解析器来使用。 而且它有很多参数可以设置,可以定制出符合用户要求的规范的XML文档格式。

网上所有的帖子、教程都是讲的内容都差不多的(就两三篇在COPY),感觉参考价值不大,而且还是讲2001年那个版本,让我很汗,不过它上一次的更新的确是2001年的(这也得怪他的开发团队更新的慢~)。

下面我就简单的说说jtidy的使用,及一些我注意到的细节吧。

Jtidy的使用非常简单,所有的功能都是通过一个类来完成的,即org.w3c.tidy.Tidy。

Tidy类用于将html转换为xml的方法有3种,每种方法对输入输出参数都有多种重载,使用方法大同小异:

 

Node

parse(java.io.InputStream in, java.io.OutputStream out)

  Reads from the given input and returns the root Node.
org.w3c.dom.
Document

parseDOM(java.io.InputStream in, java.io.OutputStream out)

  Parses InputStream in and returns a DOM Document node.
void

pprint(org.w3c.dom.Node node, java.io.OutputStream out)

  Pretty-prints a DOM Node.

 

 

 

parseDOM()是直接调用parse()的,pprint()是用于输出org.w3c.dom.Node或者org.w3c.dom.Document对象的,所以一般直接调用parse()就够了。

Jtidy使用非常简单,下面我就展示个
最简单的例子

 

Java代码 复制代码 收藏代码
  1. <span style="font-size: small;">import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.PrintWriter;
  4. import org.w3c.tidy.Tidy;
  5. publicclass Test {
  6. publicstaticvoid main(String[] args) throws Exception {
  7. Tidy tidy = new Tidy(); //使用Jtidy几乎只需要用的这一个类
  8. //设置jtidy的配置文件,当然你也可以在程序根据需要中设置
  9. tidy.setConfigurationFromFile("config.txt");
  10. tidy.setErrout(new PrintWriter("error.txt")); //输出错误与警告信息,默认输出到stdout
  11. //需要转换的文件,当然你也可以转换URL的内容
  12. FileInputStream in = new FileInputStream("original.htm");
  13. FileOutputStream out = new FileOutputStream("out.html"); //输出的文件
  14. tidy.parse(in, out); //开始转换了~~~Jtidy把所有东西都封装好了,哈哈~~
  15. out.close(); //转换完成关闭输入输出流
  16. in.close();
  17. }
  18. }
  19. </span>
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import org.w3c.tidy.Tidy;

public class Test {

    public static void main(String[] args) throws Exception {

	Tidy tidy = new Tidy();	//使用Jtidy几乎只需要用的这一个类
        //设置jtidy的配置文件,当然你也可以在程序根据需要中设置
	tidy.setConfigurationFromFile("config.txt");	
	tidy.setErrout(new PrintWriter("error.txt")); //输出错误与警告信息,默认输出到stdout
        //需要转换的文件,当然你也可以转换URL的内容
	FileInputStream in = new FileInputStream("original.htm");   
	FileOutputStream out = new FileOutputStream("out.html");    //输出的文件
	tidy.parse(in, out);	//开始转换了~~~Jtidy把所有东西都封装好了,哈哈~~
	out.close();	//转换完成关闭输入输出流
	in.close();
    }
}



 

Jtidy好用的原因是因为它定制功能很强大,Tidy类里面有一堆setter/getter函数,就是用来对功能进行定制的。


当然这些配置信息也可从一个文件读出来,该文件是一个property file,例如:

indent: auto
wrap: 72
tidy-mark: yes
doctype: omit
quote-nbsp: no
quote-ampersand: no
wrap-script-literals: yes
literal-attributes: yes
force-output: yes

 

下面列举了一些比较常用的配置(还有一大堆没列出来的,附件里面有官网给出的配置含义,可以下载来参考):
add-xml-decl:是否输出“<?xml ... ?>” declaration
enclose-text:是否将所有<p>标签闭合
enclose-block-text:给所有文本加上<p>标签,使其闭合
show-errors:是否输出错误
show-warnings:是否输出警告
quote-ampersand:是否将&输出为&amp;
quote-marks:是否将“输出为&quot;
quote-nbsp:是否将空格输出为&nbsp;
indent:是否要缩进:block-level tags
indent-spaces:每次缩进的空格数
wrap:每行最多字符数,超过则自动换行,如果为0则不自动换行
char-encoding:字符编码,类似的还有output-encoding、input-encoding
literal-attributes:是否保持attribute中的空白字符不变
force-output:遇到错误是否继续输出
numeric-entities:是否将字符输出为HTML字符实体(如&lt;、&gt;)
doctype:是否输出DOCTYPE
tidy-mark:是否要输出Jtidy的<meta>标签
drop-font-tags:是否去掉<font>、<center>标签
clean:是否要清除掉多余的标签,这对处理从MS Word中复制到Html中的内容特别有效

 

Tidy里面这么多的配置属性,要是用户不小心设了一些互相矛盾的配置怎么办?Tidy会自动将低层次的配置调整以满足高层次配置的要求。

 

配置之间具体的限制主要如下(或许还有其他的,我尚未发现):
如果enclose-block-text设为 yes,则enclose-text为yes

如果input-xml设为 yes,则output-xml为yes
如果input-xml设为 yes,则assume-xml-procins为yes
如果input-xml设为 yes,则output-xhtml为no

如果output-xhtml设为 yes,则output-xml为yes
如果output-xhtml设为 yes,则uppercase-tags为no
如果output-xhtml设为 yes,则uppercase-attributes为no

如果输出字符集不是utf-8也不是ASCII且output-xml为yes,则 add-xml-decl为yes

如果output-xml设为 yes,则quote-ampersand为yes
如果output-xml设为 yes,则hide-endtags为no



下面说说使用的时候需要注意的问题

1、注释符号被转化为html字符实体
例如:

<style type="text/css">
&lt;!-- //应当是<!--
.style1 {
color: #000000;
}
.style2 {
font-size: 14px;
}
--&gt;//应当是-->
< /style>


这是因为设了output-xml:yes

 

如果你不是想转换成xml格式,只是想输出结构良好的xhtml文档,那就不要把output-xml设为yes
This option specifies if Tidy should pretty print output, writing it as well-formed XML. Any entities not defined in XML 1.0 will be written as numeric entities to allow them to be parsed by a XML parser. The original case of tags and attributes will be preserved, regardless of other options.
这个选项会将所有DTD未定义的字符输出成numeric entities,而且会无视jtidy其他的设置。

2、输出的DocType在dom4j处理中可能导致报错
Dom4j在解释xml的时候会访问web上的dtd,如果没联网的话,dom4j就会报错,如果想避免这种问题,可以把doctype设为omit(不输出DocType信息)。

3、中文乱码解决
由于jtidy转换html的时候需要考虑字符编码,但每个网页的字符编码都可能是不同的,如果有中文信息,那么很容易产生乱码。
我的解决办法很简单,因为html文件里面一般都包含了字符编码的信息,
读进一小段来分析一下便可


以下是我是用的函数,只需读取前1024个字节,由于用到了InputStream的mark()、reset()方法,所以需要BufferedInputStream。

Java代码 复制代码 收藏代码
  1. <span style="font-size: small;"> /**
  2. * 利用正则表达式匹配html输入流中的charset信息
  3. * @param bin 由于用到了InputStream的mark()、reset()方法,<br>
  4. * 所以需要BufferedInputStream
  5. * @return 该html文件的字符编码,如果没找到则返回iso8859-1
  6. * @throws IOException
  7. */
  8. public String getEncodingOfStream(BufferedInputStream bin) throws IOException {
  9. byte[] bytes = newbyte[1024]; //存放读入的信息,一次读入1024个字节
  10. bin.mark(1024); //标记初始位置,设标记失效的最大字节数为1024
  11. int len = bin.read(bytes);
  12. String encoding;
  13. String encoding_tag = "<meta[^;]+;\\s*charset\\s*=\\s*([^\"\\s]+)[^>]*>"; //使用正则表达式匹配charset
  14. String detector = new String(bytes, 0, len, "iso8859-1"); //默认用iso8859-1,避免丢失信息
  15. Pattern encodingPattern = Pattern.compile(encoding_tag, Pattern.CASE_INSENSITIVE);
  16. Matcher m = encodingPattern.matcher(detector);
  17. if (m.find()) {
  18. encoding = m.group(1); //第1个group匹配的就是需要的字符编码
  19. } else {
  20. encoding = "iso8859-1"; //如果没找到就当做iso8859-1算了
  21. }
  22. bin.reset();
  23. return encoding;
  24. }
  25. </span>
     /**
     * 利用正则表达式匹配html输入流中的charset信息
     * @param bin 由于用到了InputStream的mark()、reset()方法,<br>
     * 所以需要BufferedInputStream
     * @return 该html文件的字符编码,如果没找到则返回iso8859-1
     * @throws IOException
     */
    public String getEncodingOfStream(BufferedInputStream bin) throws IOException {
        byte[] bytes = new byte[1024];	//存放读入的信息,一次读入1024个字节
        bin.mark(1024);	//标记初始位置,设标记失效的最大字节数为1024
        int len = bin.read(bytes);
        String encoding;
        String encoding_tag = "<meta[^;]+;\\s*charset\\s*=\\s*([^\"\\s]+)[^>]*>";   //使用正则表达式匹配charset
        String detector = new String(bytes, 0, len, "iso8859-1");   //默认用iso8859-1,避免丢失信息
        Pattern encodingPattern = Pattern.compile(encoding_tag, Pattern.CASE_INSENSITIVE);
        Matcher m = encodingPattern.matcher(detector);
        if (m.find()) {
            encoding = m.group(1);	//第1个group匹配的就是需要的字符编码
        } else {
            encoding = "iso8859-1";	//如果没找到就当做iso8859-1算了
        }
        bin.reset();
        return encoding;
    }



 

获取字符编码后,在jtidy里面setInputEncoding()一下就行了。

4、输出编码问题
由于
dom4j的默认编码是utf8的,为了方便,可以把jtidy的输出编码设为utf-8

5、输出配置信息
如果你弄了半天还是被jtidy复杂的配置弄得晕头转向,你可以把他的
配置输出来看看,方法如下:
tidy.getConfiguration().printConfigOptions(new PrintWriter(System.out), true);

 

分享到:
评论

相关推荐

    Jtidy 将HTML转化成XML

    利用Jtidy工具, 将HTML转化成XML,这里给出简单的转换方法。

    JTidy配置手册,将Html页面转化为xml

    JTidy是一款开源的Java库,专门用于清理和格式化HTML文档,同时也支持将HTML转换为XML格式。这个工具对于处理不规范或者混乱的HTML代码尤其有用,它可以帮助开发者将不规则的HTML源码整理成符合W3C标准的XML文档,...

    html转换成xml使用的Jtidy类库

    html转换成xml使用的tidy类库,很好用也很简单,

    jsoup和jtidy 对html操作,将不规范的html转换为xhtml

    在这种情况下,jsoup和Jtidy这两个Java库就显得尤为重要,它们可以帮助我们将不规范的HTML转换为更标准的XHTML(可扩展超文本标记语言)。 首先,让我们深入了解jsoup。jsoup是一款强大的Java库,设计用于处理现实...

    jtidy-r938.zip

    《Java使用JTidy将HTML转换为XML的详解》 在信息技术领域,HTML(超文本标记语言)和XML(可扩展标记语言)是两种广泛使用的数据格式。HTML主要用于网页的结构化表示,而XML则强调数据的结构和语义。在某些场景下,...

    jtidy-04aug2000r7-dev.zip_ jtidy-r938-sources_JTidy-lizi_jtidy _

    这个库的主要功能是对不规范的HTML进行清理和格式化,使其符合W3C的HTML和XHTML标准,并且能够将HTML转换为XML或XHTML格式。在"jtidy-04aug2000r7-dev.zip"这个压缩包中,包含了JTidy的一个开发版本,版本号为04aug...

    jtidy-r820

    JTidy 一个能将HTML格式转换成XML的工具。 JTidy是HTML Tidy(一个HTML语法检查器和优雅的打印编排工具)的Java移植,除了本身具有的清除HTML文件难看或错误内容的功能外,还提供了一个DOM接口,程序员可以将JTidy...

    jtidy-04aug2000r7-dev.zip

    3. **XML兼容性**:jtidy能将HTML转换为XHTML,使得原本非结构化的HTML具备了XML的结构化特性,方便进一步的XML处理。 4. **DOM操作**:jtidy提供了一套基于DOM(Document Object Model)的API,允许开发者通过Java...

    Java通过DOM+Jtidy结合Mysql实现基于本地的简单的搜索系统

    通过JTidy,我们可以读取HTML文件,将其整理成规范的XML文档,便于后续的解析和处理。 2. **DOM解析**: DOM(Document Object Model)是W3C组织推荐的一种编程接口,它将HTML或XML文档表示为一棵树形结构。Java中...

    2jtidy-04aug2000r7-dev.zip_jti_jtidy _zip

    它最初由Dave Raggett开发,旨在将不规范的HTML转换为符合W3C标准的XML或HTML。Jtidy在处理网页源码时,可以纠正许多常见的语法错误,如缺失的标签、不正确的嵌套等,并将其转换为有效的XML格式,这在处理从网络抓取...

    基于XML的web信息抽取系统

    这个系统主要利用HTML页面作为数据源,通过解析、转化和清理HTML内容,将其转换为XML格式,便于进一步的数据处理和分析。在该系统中,信息抽取(Information Extraction, IE)是核心部分,它涉及到网页内容的理解、...

    Java理论与实践:用XQuery进行屏幕搜集

    清单1展示了如何使用JTidy将HTML转换为XML DOM,从而允许通过XPath或XQuery进行后续处理。虽然XPath也是提取数据的有效工具,但XQuery的学习曲线相对较平缓,且更适合处理复杂的数据提取任务。XQuery的设计初衷是...

    java的html2word

    标题中的“Java的HTML2Word”指的是使用Java编程语言将HTML文档转换成Microsoft Word(.doc)格式的过程。这个过程通常涉及到对HTML内容的解析、处理以及格式转换,以便在Word文档中正确显示。在Java中,Apache POI...

    html文件解析器-源码

    HTML文件解析器是一种用于处理和理解HTML文档的软件工具,它能够将HTML代码转换成结构化的数据,便于进一步的分析、操作或展示。本解析器的源码简单易懂,适合初学者研究学习。 HTML(HyperText Markup Language)...

    html2pdf代码.7z

    本篇将详细介绍如何利用Jtidy和wkhtmltopdf插件在Windows及Linux环境下将HTML转换为PDF。 Jtidy是一个强大的Java库,主要用于解析、清理和重构HTML或XML文档。它能够将不规范的HTML代码转化为符合W3C标准的XHTML,...

    java把文档对象转为html

    - **JTidy**:JTidy是一个Java版本的Tidy,用于清理和格式化HTML或XML,可以在处理转换后的HTML时确保其结构正确。 2. **转换过程**: - **PDF转HTML**:使用PDFBox,首先读取PDF文件,然后遍历页面,提取文本和...

    java解析html

    4. **JTidy** - JTidy 是一个 Java 实现的 HTML/Tidy 解析器和格式化器,它可以将 HTML 转换为符合标准的 XHTML,同时也可以解析 HTML 和 XML。 这些库都提供了不同的方法来解析和操作 HTML,开发者可以根据具体...

    基于Java的实例开发源码-HTML文档解析器 HTMLParser.zip

    HTMLParser是一个轻量级的库,设计用于解析HTML文档并将其转换为可操作的数据结构,方便进一步处理。 3. **HTMLParser库**:HTMLParser库提供了一种简单的方式来处理HTML文档,支持DOM(Document Object Model)和...

Global site tag (gtag.js) - Google Analytics