使用XML::Dataset解析数据非常简单

令人难以置信的是,当涉及到XML解析时,CPAN还没有完全覆盖,但XML::Dataset是一个新的模块,填补了这一有用的空白。XML::Dataset允许你声明一个纯文本数据集合模式,然后为你提取数据,速度非常快。继续阅读,看看它是如何工作的。

需求

CPAN测试者结果显示,XML::Dataset v0.06将在任何带有Perl(低至5.8.9)的平台上运行。要使用CPAN安装模块,请打开终端并输入

$ cpan XML::Dataset

提取数据

要使用XML::Dataset,你需要一些字符串化的XML源数据和数据配置文件。配置文件只是一个指定您要提取的数据的纯文本模式。让我们看看一个例子

use strict;
use warnings;
use XML::Dataset;
use Data::Printer;

my $sample_data = q(<?xml version="1.0"?>
<colleagues>
    <colleague>
        <title>The Boss</title>
        <phone>+1 202-663-9108</phone>
    </colleague>
    <colleague>
        <title>Admin Assistant</title>
        <phone>+1 347-999-5454</phone>
        <email>inbox@the_company.com</email>
    </colleague>
    <colleague>
        <title>Minion</title>
        <phone>+1 792-123-4109</phone>
    </colleague>
</colleagues>);

my $sample_data_profile
    = q(colleagues
            colleague
                title   = dataset:colleagues
                email   = dataset:colleagues
                phone   = dataset:colleagues);

p parse_using_profile($sample_data, $sample_data_profile);

上面的代码声明了一个简单的XML数据集($sample_data)和一个数据配置文件以提取所需数据($sample_data_profile)。XML::Dataset要求数据配置文件中的每个缩进换行符映射到数据集的另一个嵌套级别。一旦我们到达我们想要提取的数据属性,我们只需将一个数据集分配给它们(dataset:colleagues)。

XML::Dataset导出“parse_using_profile”函数,该函数使用我们的数据配置文件提取数据,并返回一个Perl数据结构。我们使用Data::Printer打印结果。运行此代码,我们得到以下输出

\ {
    colleagues   [
        [0] {
            phone   "+1 202-663-9108",
            title   "The Boss"
        },
        [1] {
            email   "inbox@the_company.com",
            phone   "+1 347-999-5454",
            title   "Admin Assistant"
        },
        [2] {
            phone   "+1 792-123-4109",
            title   "Minion"
        },
    ]
}

请注意,XML::Dataset没有问题地提取了数据中存在的单个电子邮件地址,尽管其他同事没有该属性。如果我们想收集电子邮件和电话号码,但分别在单独的数据集中呢?我们只需更新$sample_data_profile,添加两个数据集即可

my $sample_data_profile
    = q(colleagues
            colleague
                title   = dataset:emails dataset:phones
                email   = dataset:emails
                phone   = dataset:phones);

重新运行代码,XML::Dataset现在为我们产生了两个数据集

\ {
    emails   [
        [0] {
            title   "The Boss"
        },
        [1] {
            email   "inbox@the_company.com",
            title   "Admin Assistant"
        },
        [2] {
            title   "Minion"
        }
    ],
    phones   [
        [0] {
            phone   "+1 202-663-9108",
            title   "The Boss"
        },
        [1] {
            phone   "+1 347-999-5454",
            title   "Admin Assistant"
        },
        [2] {
            phone   "+1 792-123-4109",
            title   "Minion"
        }
    ]
}

真实示例

让我们编写一个程序来解析一个更真实的数据集。许多网站提供网站内容的站点地图以及最后更新时间。搜索引擎使用这些信息来优化其爬行程序。站点地图有一个定义的xml格式,所以用XML::Dataset解析它非常容易

use strict;
use warnings;
use XML::Dataset;
use Data::Printer;
use HTTP::Tiny;

my $url = 'http://perltricks.com/sitemap.xml';

my $sitemap_data 
    = HTTP::Tiny->new->get($url)->{content};

my $sitemap_data_profile
    = q(urlset
            url
                loc     = dataset:sitemap_locations_modified
                lastmod = dataset:sitemap_locations_modified);

p parse_using_profile($sitemap_data, $sitemap_data_profile);

上面的代码使用HTTP::Tiny下载PerlTricks.com的站点地图,并从站点地图中提取每个URL和最后修改时间戳。运行代码,我们得到以下输出

\ {
    sitemap_locations_modified   [
        [0]  {
            lastmod   "2014-05-09",
            loc       "http://perltricks.com/"
        },
        [1]  {
            lastmod   "2013-03-24",
            loc       "http://perltricks.com/article/1/2013/3/24/3-quick-ways-to-find-out-the-version-number-of-an-installed-Perl-module-from-the-terminal"
        },
        [2]  {
            lastmod   "2013-03-27",
            loc       "http://perltricks.com/article/3/2013/3/27/How-to-cleanly-uninstall-a-Perl-module"
        },
        ...
    ]
}

没问题!我们可以重用那个相同的程序来下载和解析互联网上的任何站点地图。

结论

XML::Dataset非常适合从XML中提取固定数据模式。纯文本数据配置文件非常易于使用,非程序员也可以编写它们。XML::Dataset也非常快:底层使用XML::LibXML(和一些优化)并可以适应格式良好的HTML。它有很好的文档,并提供一些高级功能,如部分数据集解析分发。模块作者James Spurin因制作高质量的模块并为CPAN的XML命名空间添加了受欢迎的补充而应受到赞誉。

您有没有一个很喜欢的CPAN模块想要我们介绍?给我们发电子邮件

封面图片© Duncun Hull


本文最初发布于PerlTricks.com

标签

David Farrell

David是一位专业程序员,他经常推文博客关于代码和编程艺术。

浏览他们的文章

反馈

这篇文章有问题吗?请通过在GitHub上创建问题或拉取请求来帮助我们。