admin 管理员组

文章数量: 887032


2024年1月10日发(作者:crontab在线生成)

/blog/730337

2010-08-05

html to xml:Jtidy的使用及注意事项(jtidy-r938)

文章分类:Java编程

最近在做一个项目,要把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的使用非常简单,所有的功能都是通过一个类来完成的,即。

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

Node

parse (tream in, Stream out)

Reads from the given input and returns the root Node.

.

parseDOM (tream in, Stream

Document

out)

Parses InputStream in and returns a DOM Document node.

void

pprint ( node, Stream out)

Pretty-prints a DOM Node.

parseDOM()是直接调用parse()的,pprint()是用于输出或者nt对象的,所以一般直接调用parse()就够了。

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

Java代码

1. import putStream;

2. import tputStream;

3. import riter;

4. import ;

5.

6. public class Test {

7.

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

9.

10. Tidy tidy = new Tidy(); //使用Jtidy几乎只需要用的这一个类

11. //设置jtidy的配置文件,当然你也可以在程序根据需要中设置

12. figurationFromFile("");

13. out(new PrintWriter("")); //输出错误与警告信息,默认输出到stdout

14. //需要转换的文件,当然你也可以转换URL的内容

15. FileInputStream in = new FileInputStream("");

16. FileOutputStream out = new FileOutputStream("");

//输出的文件

17. (in, out); //开始转换了~~~Jtidy把所有东西都封装好了,哈哈~~

18. (); //转换完成关闭输入输出流

19. ();

20. }

21.}

22.

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:是否输出“” declaration

enclose-text:是否将所有

标签闭合

enclose-block-text:给所有文本加上

标签,使其闭合

show-errors:是否输出错误

show-warnings:是否输出警告

quote-ampersand:是否将&输出为&

quote-marks:是否将“输出为"

quote-nbsp:是否将空格输出为 

indent:是否要缩进:block-level tags

indent-spaces:每次缩进的空格数

wrap:每行最多字符数,超过则自动换行,如果为0则不自动换行

char-encoding:字符编码,类似的还有output-encoding、input-encoding

literal-attributes:是否保持attribute中的空白字符不变

force-output:遇到错误是否继续输出

numeric-entities:是否将字符输出为HTML字符实体(如<、>)

doctype:是否输出DOCTYPE

tidy-mark:是否要输出Jtidy的标签

drop-font-tags:是否去掉

标签

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字符实体

例如:

这是因为设了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. /**

2. * 利用正则表达式匹配html输入流中的charset信息

3. * @param bin 由于用到了InputStream的mark()、reset()方法,

4. * 所以需要BufferedInputStream

5. * @return 该html文件的字符编码,如果没找到则返回iso8859-1

6. * @throws IOException

7. */

8. public String getEncodingOfStream(BufferedInputStream bin)

throws IOException {

9. byte[] bytes = new byte[1024]; //存放读入的信息,一次读入1024个字节

10. (1024); //标记初始位置,设标记失效的最大字节数为1024

11. int len = (bytes);

12. String encoding;

13. String encoding_tag = "]*>"; //使用正则表达式匹配charset

14. String detector = new String(bytes, 0, len, "iso8859-1"); //默认用iso8859-1,避免丢失信息

15. Pattern encodingPattern = e(encoding_tag, _INSENSITIVE);

16. Matcher m = r(detector);

17. if (()) {

18. encoding = (1); //第1个group匹配的就是需要的字符编码

19. } else {

20. encoding = "iso8859-1"; //如果没找到就当做iso8859-1算了

21. }

22. ();

23. return encoding;

24. }

25.

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

4、输出编码问题

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

5、输出配置信息

如果你弄了半天还是被jtidy复杂的配置弄得晕头转向,你可以把他的 配置输出来看看 ,方法如下:

figuration().printConfigOptions(new

PrintWriter(), true);


本文标签: 输出 字符 编码