Perl XML FAQ

Perl XML FAQ

Version 1.1中文版

by Jonathan Eisenzopf
邵宛澍翻譯


Credits

感謝Clark Cooper, Matthew Sergeant, Enno Derksen,
Ken MacLeod, Rob Cameron, Asakura Hiroshi以及Wanshu Shao(邵宛澍)對此FAQ作出的奉獻.


Overview

這份FAQ包含了通過Perl使用及操作XML的信息. 如果有任何的糾錯或添加信息要求,請直接發電子郵件給
eisen@pobox.com. 這份FAQ可以在http://www.perlxml.com/faq/perl-xml-faq.html找到.
Asakura Hiroshi為這份FAQ建立了一個日語譯文,可以在http://db-www.aist-nara.ac.jp/xml/perl-xml-faq-j.html找到,
Wanshu Shao(邵宛澍)為這份FAQ建立一個簡體中文譯本, 可以在http://www.linux.org.cn/xml/perl-xml-faq-cn.html找到.
這份FAQ的信息主要基於在Perl XML郵件列表中的討論和來往的信件. 如果想加入該列表,可以發送電子郵件給 Lyris@ActiveState.com,
並在正文中寫清: SUBSCRIBE Perl-XML.

這份FAQ通過一小段Perl腳本和一個XML文件生成. 這份腳本可以從 http://www.perlxml.com/faq/xmlfaq.pl獲得.
而XML的源文件則可以在 http://www.perlxml.com/faq/perl-xml-faq.xml獲得.
如想生成這份 Perl XML FAQ, 運行 perl xmlfaq.pl perl-xml-faq.xml 將會在STDOUT中打印出HTML.


Q1

到底什麼是XML?

可擴展標註語言(eXtensible Markup Language),或XML,是由 World
Wide Web Consortium 發展起來的SGML語言的一個簡化版本. 不同於HTML只提供了有限的標記定義, XML允許作者根據他們文檔的邏輯結構定義標記.
http://www.xml.com/xml/pub/98/10/guide0.html上有一份很好的關於XML的介紹.
更多的關於XML的信息則可以在 http://www.w3.org/XML找到.


Q2

有Perl專用的XML解析器嗎?

是的. 有一些Perl專用的解析器, 但最歡迎的是 XML::Parser 模塊. 起先由 Larry
Wall 開發, 現在由 Clark Cooper
負責維護 XML::Parser 模塊. 這個模塊是Expat的 Perl 外殼, Expat是由James Clark由C寫的一個非驗證性解析器.
該模塊可以在任何CPAN服務器或者Clark在 http://www.netheaven.com/~coopercc/xmlparser/intro.html的主頁上找到.
分發版中包含了 Expat, 因此你不用為需要單獨安裝它而擔心. 關於Expat的更多信息在 http://www.jclark.com/xml/expat.html.
Clark Cooper同時也寫一個非常好的關於 XML::Parser 的介紹, 可以在 http://www.xml.com/xml/pub/98/09/xml-perl.html找到.

在某些情況中, 你可能在處理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://www2.ann.ne.jp/~kojun/TmpL1/
找到.


Q9

有沒有關於XSL的?

因為XSL還在大幅發展, 目前還沒有什麼興趣建立供Perl應用的XSL引擎. 因此, 如果你非常想看一看的話,
就在Perl-XML郵件列表中大聲呼吁吧.


Q10

CPAN中的XML模塊在哪裏?

如果你在CPAN中尋找 XML::Parser 或其它的模塊碰到了問題, 可以嘗試以下的鏈接:
http://www.perl.com/CPAN-local/modules/by-category/11_String_Lang_Text_Proc/XML/.
一個關於所有Perl/XML模塊並且附帶描述的列表可以在 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

有可以從一個流中讀入數個文檔嗎?

你可以在parseparse_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文檔的時間.


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.

Leave a Reply

Your email address will not be published. Required fields are marked *