DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 快速開始Perl XML:接口篇
快速開始Perl XML:接口篇
編輯:XML詳解     

入門簡介

最近在Perl-XML郵件組經常問起的問題是如何給不熟悉的用戶一個對大量 Perl XML 模塊的快速指引性概述文檔。在接下來的幾個月裡我將單獨對此問題寫幾篇專欄文章。

CPAN上的XML模塊可以分成三大類:對 XML 數據提供獨特的接口(通常有關在XML實例和Perl數據之間的轉換),實現某一標准XML API的模塊,和對一些特定的XML相關任務進行簡化的特殊用途模塊。這個月我們先關注第一個,XML Perl專用接口。

use Disclaimer qw(:standard);

此文檔不是為了對模塊性能進行基准測試,我的目的也不是暗示某一模塊比另一個模塊更有用。為你的項目選擇正確的 XML 模塊更多依賴於項目本身和你積累的經驗。不同的接口適應於不同的任務和不同的人。我的唯一目的是通過定義兩個簡單的任務,然後提供不同借口的可運行例子來顯示如何獲得同樣的最終結果。

任務

雖然XML的用途非常多,但大部分XML相關任務可分成兩組:一是從已有的XML文檔提取數據,另一個是使用其他資源的數據創建一個新的XML文檔。既然如此,我們所用來介紹不同模塊的例子將由“從一個XML文件中提取某一特定數據集”和“將一Perl數據結構轉為某一特定XML格式”組成。

任務一:提取數據

首先,假設有如下XML片斷:

<?XML version="1.0"?>
<camelids>
  <species name="Camelus dromedarius">
    <common-name>Dromedary, or Arabian Camel</common-name>
    <physical-characteristics>
      <mass>300 to 690 kg.</mass>
      <appearance>
        The dromedary camel is characterized by a long-curved 
        neck, deep-narrow chest, and a single hump.
        ...
      </appearance>
    </physical-characteristics>
    <natural-history>
       <food-habits>
         The dromedary camel is an herbivore.
         ...
       </food-habits>
       <reproduction>
         The dromedary camel has a lifespan of about 40-50 years
         ...
       </reproduction>
       <behavior>
         With the exception of rutting males, dromedaries show
         very little aggressive behavior.
         ...
       </behavior>
       <habitat>
         The camels prefer desert conditions characterized by a
         long dry season and a short rainy season.
         ...
       </habitat>
    </natural-history>
    <conservation status="no special status">
      <detail>
        Since the dromedary camel is domesticated, the camel has
        no special status in conservation.
      </detail>
    </conservation>
  </specIEs>
  ...
</camelids>
現在我們假設此完整文檔(可從本月例子代碼中獲取)包含駱駝家族所有成員的全部信息,而不僅僅是上面的單峰駱駝信息。為了舉例說明每一模塊是如何從此文件中提取某一數據子集,我們將寫一個很簡短的腳本來處理camelids.XML文檔和在STDOUT上輸出我們找到的每一種類的普通名(common-name),拉丁名(用括號包起來),和當前保存狀況。因此,處理完整個文檔,每一個腳本的輸出應該為如下結果:
Bactrian Camel (Camelus bactrianus) endangered 
Dromedary, or Arabian Camel (Camelus dromedarius) no special status 
Llama (Lama glama) no special status 
Guanaco (Lama guanicoe) special concern
Vicuna (Vicugna vicugna) endangered

任務二:創建一個XML文檔

為了示范每一模塊是如何從其他數據源中創建新的XML文檔,我們將寫一個小腳本將一個簡單的Perl hash轉換為一個簡單的XHtml文檔。hash裡包含一些指向很cool的特定相關駱駝的網頁的URLs。

Hash 如下:

my %camelid_links = (
    one   => { url         => '
    http://www.online.discovery.com/news/picture/may99/photo20.html',
               description => 'Bactrian Camel in front of Great ' .
                              'Pyramids in Giza, Egypt.'},
    two   => { url         => 'http://www.fotos-online.de/english/m/09/9532.htm',
               description => 'Dromedary Camel illustrates the ' . 
                              'importance of Accessorizing.'},
    three => { url         => 'http://www.eskimo.com/~wallama/funny.htm',
               description => 'CharlIE - biography of a narcissistic llama.'},
    four  => { url         => 'http://arrow.colorado.edu/travels/other/turkey.Html',
               description => 'A visual metaphor for the perl5-porters ' .
                              'list?'},
    five  => { url         => 'http://www.galaonline.org/pics.htm',
               description => 'Many cool alpacas.'},
    six   => { url         => 'http://www.thpf.de/suedamerikareise/galerIE/vicunas.htm',
               description => 'Wild Vicunas in a scenic landscape.'}
);
而我們所期望從hash中創建的文檔例子為:

<?XML version="1.0">
<html>
  <body>
    <a href="http://www.eskimo.com/~wallama/funny.htm">CharlIE - 
      biography of a narcissistic llama.</a>
    <a href="http://www.online.discovery.com/news/picture/may99/photo20.html">Bactrian
      Camel in front of Great Pyramids in Giza, Egypt.</a>
    <a href="http://www.fotos-online.de/english/m/09/9532.htm">Dromedary
      Camel illustrates the importance of Accessorizing.</a>
    <a href="http://www.galaonline.org/pics.htm">Many cool alpacas.</a>
    <a href="http://arrow.colorado.edu/travels/other/turkey.html">A visual 
      metaphor for the perl5-porters list?</a>
    <a href="http://www.thpf.de/suedamerikareise/galerIE/vicunas.htm">Wild
      Vicunas in a scenic landscape.</a>
  </body>
</Html>
良好縮進的XML結果文件(如上面所顯示的)對於閱讀很重要,但這種良好的空格處理不是我們案例所要求的。我們所關心的是結果文檔是結構良好的/well-formed和它正確地表現了hash裡的數據。

任務定義完畢,接下來該是代碼例子的時候了。

XML Perl專用接口例子

XML::Simple

最初創建用來簡化讀寫XML格式配置文件的XML::Simple, 在轉換XML文檔和Perl數據結構之間沒有另外的抽象接口。所有的元素和屬性都可以通過嵌套的引用直接讀取。

Reading

use XML::Simple;

my $file = 'files/camelids.xml';
my $xs1 = XML::Simple->new();

my $doc = $xs1->XMLin($file);

foreach my $key (keys (%{$doc->{species}})){
   print $doc->{species}->{$key}->{'common-name'} . ' (' . $key . ') ';
   print $doc->{specIEs}->{$key}->{conservation}->final . "\n";
}

Writing

use XML::Simple;

require "files/camelid_links.pl";
my %camelid_links = get_camelid_data();

my $xsimple = XML::Simple->new();

print $xsimple->XMLout(\%camelid_links,
                       noattr => 1,
                       XMLdecl => '');
這數據到文檔的任務的條件要求暴露了XML::Simple的一個弱點:它沒有允許我們決定hash裡的哪個key應該作為元素返回和哪個key該作為屬性返回。上面例子的輸出雖然接近我們的輸出要求但還遠遠不夠。對於那些更喜歡將XML文檔內容直接作為Perl數據結構操作,而且需要在輸出方面做更細微控制的案例,XML::Simple和XML::Writer配合得很好。

如下例子說明了如何使用XML::Write來符合我們的輸出要求。

use XML::Writer;

require "files/camelid_links.pl";
my %camelid_links = get_camelid_data();

my $writer = XML::Writer->new();

$writer->XMLDecl();
$writer->startTag('html');
$writer->startTag('body');

foreach my $item ( keys (%camelid_links) ) {
    $writer->startTag('a', 'href' => $camelid_links{$item}->{url});
    $writer->characters($camelid_links{$item}->{description});
    $writer->endTag('a');
}

$writer->endTag('body');
$writer->endTag('Html');

$writer->end();

XML::SimpleObject

XML::SimpleObject 對XML數據使用回想文檔對象模型(Document Object Model)的存取器/Accessor來提供一個面對對象接口。

Reading

use XML::Parser;
use XML::SimpleObject;

my $file = 'files/camelids.xml';

my $parser = XML::Parser->new(ErrorContext => 2, Style => "Tree");
my $xso = XML::SimpleObject->new( $parser->parsefile($file) );

foreach my $species ($xso->child('camelids')->children('species')) {
    print $species->child('common-name')->{VALUE};
    print ' (' . $species->attribute('name') . ') ';
    print $specIEs->child('conservation')->attribute('status');
    print "\n";
}

Writing

XML::SimpleObject 沒有通過抓取來創建XML文檔的功能。但是與上面的XML::Simple例子一樣,可以通過與XML::Writer配合簡單的完成任務。

XML::TreeBuilder

XML::TreeBuilder 包由兩模塊組成:XML::Element用來創建和獲得XML元素點的內容和XML::TreeBuilder作為一個工廠包從已有XML文件中簡化文檔樹的創建。對於那些已有值得尊敬的 HTML::Element 和 Html::Tree 模塊使用經驗的人來說,使用 XML::TreeBuilder 是非常容易的,因為除了XML特有的方法外其他都是一樣的。

Reading

use XML::TreeBuilder;

my $file = 'files/camelids.xml';
my $tree = XML::TreeBuilder->new();

$tree->parse_file($file);

foreach my $species ($tree->find_by_tag_name('species')){
    print $species->find_by_tag_name('common-name')->as_text;
    print ' (' . $species->attr_get_i('name') . ') ';
    print $specIEs->find_by_tag_name('conservation')->attr_get_i('status');
    print "\n";
}

Writing

use XML::Element;

require "files/camelid_links.pl";
my %camelid_links = get_camelid_data();


my $root = XML::Element->new('Html');
my $body = XML::Element->new('body');
my $xml_pi = XML::Element->new('~pi', text => 'xml version="1.0"');
$root->push_content($body);

foreach my $item ( keys (%camelid_links) ) {
    my $link = XML::Element->new('a', 'href' => $camelid_links{$item}->{url});
    $link->push_content($camelid_links{$item}->{description});
    $body->push_content($link);
}

print $xml_pi->as_XML;
print $root->as_XML();

XML::Twig

XML::Twig 與其他只有Perl的XML接口不同,它是一個除了標准的XML APIs外還有其它富有創造性特點的Perlish接口。需要更多更詳細的介紹請查看XML.com 文章

Reading

use XML::Twig;

my $file = 'files/camelids.xml';
my $twig = XML::Twig->new();

$twig->parsefile($file);

my $root = $twig->root;

foreach my $species ($root->children('species')){
    print $species->first_child_text('common-name');
    print ' (' . $species->att('name') . ') ';
    print $specIEs->first_child('conservation')->att('status');
    print "\n";
}

Writing


use XML::Twig;

require "files/camelid_links.pl";
my %camelid_links = get_camelid_data();

my $root = XML::Twig::Elt->new('Html');
my $body = XML::Twig::Elt->new('body');
$body->paste($root);

foreach my $item ( keys (%camelid_links) ) {
    my $link = XML::Twig::Elt->new('a');
    $link->set_att('href', $camelid_links{$item}->{url});
    $link->set_text($camelid_links{$item}->{description});
    $link->paste('last_child', $body);
}

print QQ|<?XML version="1.0"?>|;
$root->print;
這些例子舉例說明了這些普通XML Perl模塊的基本使用方法。我的目標是提供足夠多的例子讓你感受怎麼用每個模塊寫代碼。下個月我們將關注“實現某一標准XML API的模塊”,特別說明的,XML::DOM, XML::XPath 和其他大量的 SAX 和類SAX模塊。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved