Perl-XML-FAQ

取自 PerlChina.org - wiki

跳转到: 导航, 搜索
  • 原 名:Perl XML FAQ - Version 1.1
  • 翻 译:邵宛澍
  • 审 校:子程(JackyCheng)
  • 出 处:中国Perl协会 FPC
  • 作 者:Jonathan Eisenzopf(Dec 1998)
  • 原 文:
  • 归 档:2005-04-09
  • Perlchina提醒您:请保护作者的著作权,维护作者劳动的结晶。


目录


:这篇文章出自 1998 年, 可以在这里看到最新的 "Perl XM FAQ" 文章. 不同人撰写


[编辑] Q1. 何谓 XML?

XML中文全称为可扩展标注语言 (eXtensible Markup Language),,简称XML,,是由 World Wide Web Consortium 发展起来的 SGML 语言的一个简化版本。不同于 HTML 只提供了有限的标记定义,XML 允许作者根据他们文档的逻辑结构定义标记 . 在 http://www.xml.com/xml/pub/98/10/guide0.html 上有一份很好的有关于 XML 的介绍。更多有关于 XML 的信息可以在W3组织的 http://www.w3.org/XML 上找到 .

[编辑] Q2. 有 Perl 专用的 XML 解析器吗 ?

是的。有有很多作者都为Perl写了一些有关于XML的解析器,但最受欢迎还是 XML::Parser 模块(可以在 [www.cpan.org PERL典藏网] 或者 http://www.netheaven.com/~coopercc/xmlparser/intro.html[链接失效] Clark的主页上找到)。这个PM最先由 Larry Wall (PERL的原作者)负责开发,后来由 Clark Cooper 负责维护。而这个模块起初只是基于 Expat 的 Perl Hacks,而 Expat 则是由 James Clark 用 C 写的一个非验证性的XML解析器。模块的分发版当中已经包含了 Expat,所以你不用担心去如何安装Expat了。关于 Expat 的更多信息在 http://www.jclark.com/xml/expat.html[链接失效] 找到。 Clark Cooper 同时也写一个非常好的关于 XML::Parser 的介绍 ,可以在 http://www.xml.com/xml/pub/98/09/xml-perl.html 找到。唐宗汉先生也在CPAN数来宝中介绍了有关于这个模块的使用,可以在 http://www.autrijus.org/cpanmods/ 找到。 在某些情况下,你可能在想在处理 XML 时使用正则表达式 。那么由 Rob Cameron 用 Perl 编写的 REX 就是一个可以满足你需求的初级解析器,REX 可以在 http://www.cs.sfu.ca/~cameron/REX.html 找到 。

[编辑] Q3. 我需要什么版本的 Perl 来使用 XML::Parser?

你应该安装有 Perl 5.004 或更高的版本。如果你还需要 UTF8 编码的支持,则需要有 5.005_52或者更高版本的支持 > http://www.perl.com 是相当好的 Perl 资源站 . 要获得最新的 Perl 分发版,可以访问 http://www.perl.com/CPAN 并选择离你最近 CPAN 镜像站点。

[编辑] Q4. 我是否可以使用 XML::Parser 来代替 DTD 去验证 XML?

不可以。XML::Parser 建立于 Expat 之上 , Expat 是一个非验证解析器,所以一个 DOCTYPE 声明会受到语法上的检查 ,因此则不能用于验证 XML 。然而 ,Earl Hood 写了一个 叫做perlSGML的工具,它包含了一些有关于Perl的脚本和库,可以帮助用户解析和操纵 SGML。同时,它还包含了处理 DTD 的能力 . 查看 http://www.oac.uci.edu/indiv/ehood/perlSGML.html 以获得更多的信息。你也可以尝试一下 David Megginson 的 SGMLspm 模块 ,可以在 http://www.perl.com/CPAN/authors/David_Megginson 找到,它可以用来解析 James Clark 的 NSGMLS 解析器的输出。你可以在 http://www.jclark.com/sp/index.htm [链接失效]找到已经包含了 NSGML 的 SP 工具集。

[编辑] Q5. 我如何在 Win32 下安装 XML::Parser?

XML::Parser 可以在 ActiveState 的模块里找到 . 可以通过在命令行中输入 : 'ppm install XML-Parser' 来进行安装 . Matt Sergeant 通常提供比 ActiveState 更新的 XML::Parser 版本 , 可以命令 'ppm install --location=http://www.fastnetltd.ndirect.co.uk/Perl/packages XML-Parser' [链接失效] 来安装 .

[编辑] Q6. XML::Parser 是面向对象的模块吗 ?

简单地说 , 是的 . XML::Parser 是用来生产 XML::Parser::Expat 需要的实例的生产厂家 .

[编辑] Q7. XML::Parser 是否基于 SAX API?

不基于。XML::Parser 基于 Expat, 一个由 James Clark 写的非验证解析器 . 然而 , Eric Prud'hommeaux 开发了一个简单的实现方案 , 叫做 W3C::SAX::XmlParser, 它可以在 http://www.w3.org/1999/02/26-modules/ 找到 . 注意 , 这个实现方案并非最终结果 , 因为 Ken Macleod 目前正在从事标准的 Perl-SAX 接口工作.

[编辑] Q8. 有没有供 Perl 使用的 DOM 模块 ?

有. Enno Derksen 正与 Clark Cooper 合作编写一个供 Perl 使用的 DOM 模块 , 它是一个实现 XML::Parser 的子类 . 它用 DOM level 1 语法编译 . 如果你想使用它的话 , 你需要安装有 XML::Parser 版本 2.16 或更高 . 该模块可以在你当地的 CPAN 档案中找到 , 同时也存放在 http://www.erols.com/enno/dom/ [链接失效] 之中 . 另外还有一个使用自带 XML 解析器的可以在 http://www.ueno-kojun.com/<nowiki> [作者已不再更新] 找到 . ==Q9. 有没有关于 XSL 的 ?== 因为 XSL 还在大幅发展 , 所以目前还没有什么兴趣建立供 Perl 应用的 XSL 引擎 . 因此 , 如果你非常想看一看的话 , 就在 Perl-XML 邮件列表中大声呼吁吧 . ==Q10. CPAN 中的 XML 模块在哪里 ?== 如果你在 CPAN 中寻找 XML::Parser 或其它的模块碰到了问题 , 可以尝试以下的链接 : http://search.cpan.org/modlist/String_Language_Text_Processing/XML 一个关于所有 Perl/XML 模块并且附带描述的列表可以在 <nowiki>http://www.perlxml.com/modules/perl-xml-modules.html [链接已失效] 找到.

[编辑] Q11. XML::DOM 和 XML::Grove 之间有什么区别 ? 我该使用哪一个 ?

XML::DOM 是一个 World Wide Web Consortium (W3C) 的 Document Object Model (DOM) Level 1 的实现 . DOM 定义了一个用于 XML 树的接口,而 XML::DOM 则是 DOM 的一个实现 , 其工作于在内存中的 XML 结点树 。所有的 DOM 实现 (Perl 或是其它语言 ) 均使用类似的接口 , 并且用一种 DOM 可以实现的话 , 用另一种也可以 . 这个便捷性允许按你的需要 ( 内存使用 , 实现语言 , 数据库等 ) 来选择你需要的 DOM 实现方案.
XML::Grove 使用的 Perl 的数组和 hash 来存放 XML 对象并允许你使用常规的 Perl 数组和 hash 函数来操作 XML 结点树 . XML::Grove 基于国际标准化组织 (International Organization for Standardization (ISO)) 的 HyTime 和 DSSSL 标准所描述的 "property sets".
使用 XML::DOM 使你更易于把持将代码转出到别的语言或别其它的 DOM 模块 [XML::DOM 在目前是从 Perl 转出的唯一实现方法 ], 反之亦然 . XML::Grove 有一个简单的 Perl 接口 . 粗略地读一读 XML::DOM 和 XML::Grove pod 文档可以帮助你选择使用哪一个模块 . 许多模块可以同时与 DOM 和 groves[*] 使用 , 但你需要检查一下该模块的兼容性 .

[编辑] Q12. 为什么当我在 XML 文件顶端使用了 XML 声明时, XML::Parser 就会报错 ?

可能因为你的 XML 文件中的 XML 声明不正确。管看上去 你的 XML 与大小写无关 , 然而事实上正好相反。 声明必须使用小写字符并用包含版本号(同样要小写). 它看上去是这样的:你也可以在此声明语言编码以及该文档是否是独立的: 注意 : 在 XML 声明的属性中 , 你可以使用单引号或双引号 .

[编辑] Q13. 当我使用 XML::Parser 时 ,我得到一个 : Can't find method "read" in module FileHandle 的错误信息

这个错误出现在同时与 DBI 一起使用 XML::Parser 时 . 这并不是 XML::Parser 或 DBI 的漏洞 , 而是 Perl 本身的漏洞 . 你需要将 DBI 升级到 1.05 版本或更高 , 也可以简单地用 use FileHandle; 来调用文件句柄.

[编辑] Q14. 我该如何不退出代码就获得 XML::Parser 的错误返回信息 ?

通常 , XML::Parser 模块在遇到非良构的 XML 时就会立刻终止 . 事实上 , 这是 XML 解析器应该做出的反应 . 然而在某些情况下 , 你希望不退出程序就处理错误 . 在这种时候 , 你可以在 eval 块中调用 parse() 或 parsefile() 方法 , 就象 :

eval { $p->parse($xml) };
or like:
eval { $p->parsefile($filename) };
如果有错误出现, 它会将错误消息放到 $@ 变量中. 下面是一小段解析 XML 文件的脚本. 它在一个 eval 块中包含了 parsefile() 方法, 当错误出现的时候, 就可以打印出来.
 
use strict;
use XML::Parser;
my $p = new XML::Parser();
die "catch_error.pl \n" unless $ARGV[0] && -e $ARGV[0];
eval { $p->parsefile($ARGV[0]) }; 
print "Caught error: $@\n" if $@;
print "Done.\n"; 

[编辑] Q15. 看上去 XML::Parser 把我的文本转换成了 UTF8. 有没有办法保持我原来的编码 ?

有的, 使用 original_string 方法, 包含于 2.19 或更高的版本中, 它按照字符本身的编码返回值. 唯一的缺点是它将禁止实体扩充. 同时, 当你在使用 XML::Parser::ExpatNB 对象时, 你无法使用该方法, 这个对象在版本 2.22 中被引入 .

[编辑] Q16. 有可以从一个流中读入数个文档吗?

可以。你可以在 parse 或 parse_file 中使用 parse_start 方法来从一个流中读入多个文档 . 它将建立一个新的 XML::Parser::ExpatNB 实例. 多个文档通过相继调用parse_more 方法而被解析. 调用 parse_done 方法则表示你完成了文档的处理.

[编辑] Q17. 我如何在处理文本的同时过滤掉多余的空白?

你可以在文本句柄中过滤掉多余的空白:
sub text { 
    my ($xp, $data) = @_; 
    return if ($ignorable_whitespace{$xp->current_element} and
 $data =~ /^\s*$/m); # Rest of processing ... 
}

[编辑] Q18. 当某个元素有多个属性时 , 我在 XML::Parser 2.20 中得到一个 'duplicate attribute' 错误信息.

这是 XML::Parser 2.20 中的一个漏洞 , 可以升级到新的版本 .

[编辑] Q19. 即使 XML 是正常的 , 我依然得到奇奇怪怪的 有关于XML::Parser 错误信息.

如果你使用的 Perl 是 Linux RedHat-5.2 封装分发的 , 应该升级到一个新的 Perl 版本 . Redhat 意外地在他们的 5.2 分发版中带了一个有漏洞的 Perl.

[编辑] Q20. 有没有可以解析 RDF 的模块 ?

有, Eric Prud'hommeaux 开发了一个 W3C::Rdf::RdfParser, 它需要在第 7 个问题中提到 SAX 的 Perl 实现 .可以 http://www.w3.org/1999/02/26-modules/ 找到.

[编辑] Q21. 我如何能够提高 XML::Parser 在服务器上处理文档的速度 ?

对于初学者来说 , 如果你使用 Apache, 应该安装 http://perl.apache.org 的 mod_perl. 它可以减少调用 Perl 解译器以及任何你使用的模块的时间 . 如果你还想要更快的话 , 可以使用 Data::Dumper 或 Storable 将 XML::Parser 的对象存到硬盘上 . 这能减少重复解析 XML 文档的时间.

感谢

感谢 Clark Cooper, Matthew Sergeant, Enno Derksen, Ken MacLeod, Rob Cameron, Asakura Hiroshi 以及 Wanshu Shao( 邵宛澍 ),TsangTszChing( 曾子程 ) FAQ 作出的奉献.

_Copyright (c)1998 Jonathan Eisenzopf. All rights reserved. Permission is hereby granted to freely distribute this document provided that all credits and copyright notices are retained._


PS:这篇文章译的很棒,除了一些两岸的用语差别外,其他基本上没什么修改......真希望这样的文章多一些。另外很多链接都失效了,我也不知道怎么办,所有不能link我都有标注。老大看看怎么办吧。JackyCheng

这篇文章就是太旧了些,因为我不使用 XML, 不知道文章内容是否已经过时了? 至于失效的链接, 如果可以通过 google 找到最好. 那个最新的 Perl XML FAQ 是我贴出这篇文章时尝试找最新版本时发现的. Jacky 你对 XML 熟么? 我也会在论坛里贴个帖子希望有使用 XML 的朋友对文章评估一下. 看看是否还有价值? 这篇文章最后感谢一个叫 曾子程 的, 呵呵. qiang ----PS:就是我哦,顺便加上了:) JackyCheng

原文连接好象不对? 另外此文太早。作为PerlChina的文章是否合适?和原翻译作者联系过没有? by easunlee

贴出前我联系到作者了. :) 另原文地址不对,去掉了. 关于文章是否太旧, 我在 wiki 和 bbs 都提到了. jackeycheng 说还可以. qiang

恩,那就OK 了。内容并没有过时。都很实用的东西。呵呵:)by easunlee

个人工具