新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 关于 XML 的一般性技术讨论,提供 XML入门资料 和 XML教程
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 XML基础 』 → (重发)[FPC文章]快速开始Perl XML:接口篇 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 16402 个阅读者浏览上一篇主题  刷新本主题   平板显示贴子 浏览下一篇主题
     * 贴子主题: (重发)[FPC文章]快速开始Perl XML:接口篇 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     longshentailang 帅哥哟,离线,有人找我吗?
      
      
      威望:1
      等级:计算机学士学位
      文章:325
      积分:2990
      门派:XML.ORG.CN
      注册:2006/6/20

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给longshentailang发送一个短消息 把longshentailang加入好友 查看longshentailang的个人资料 搜索longshentailang在『 XML基础 』的所有贴子 引用回复这个贴子 回复这个贴子 查看longshentailang的博客楼主
    发贴心情 (重发)[FPC文章]快速开始Perl XML:接口篇

    不好意思,这篇文章给发错了,发到建议与意见栏目去了,现在重新发在此。

    [FPC文章]快速开始Perl XML:接口篇

    翻  译:fayland
    出  处:中国Perl协会 FPC(Foundation of Perlchina)
    原  名:Perl XML Quickstart: The Perl XML Interfaces
    作  者:Kip Hampton
    原  文:http://www.xml.com/pub/a/2001/04/18/perlxmlqstart1.html
    发  表:April 18, 2001
    Perlchina提醒您:请保护作者的著作权,维护作者劳动的结晶。


    入门简介
    最近在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 version="1.0">');

    这数据到文档的任务的条件要求暴露了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模块。

    Resources
    下载案例代码
    CPAN上XML模块的完整列表
    Perl-XML邮件组档案
    使用 XML::Twig
    Second Part: Perl XML Quickstart: The Standard XML Interfaces


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/6/29 22:11:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 XML基础 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/3 7:01:41

    本主题贴数1,分页: [1]

     *树形目录 (最近20个回帖) 顶端 
    主题:  (重发)[FPC文章]快速开始Perl XML:接口篇(10851字) - longshentailang,2006年6月29日

    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    82.031ms