XML 解析和生成

概述

XML(可扩展标记语言,eXtensible Markup Language)是一种用于存储和传输数据的标记语言。它被广泛用于配置文件、数据交换、Web服务等场景。在Perl中,我们可以使用模块来解析和生成XML文档。本教程将介绍如何使用Perl进行XML的解析和生成。

1. XML 解析

1.1 使用 XML::Simple 模块

XML::Simple 是一个简单易用的模块,适合解析简单的XML文档。

1.1.1 安装 XML::Simple

首先,确保你已经安装了 XML::Simple 模块。如果没有安装,可以使用以下命令进行安装:

cpan XML::Simple

1.1.2 解析 XML 文档

以下是一个简单的XML文档示例:

<bookstore>
    <book category="COOKING">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
    </book>
    <book category="CHILDREN">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
</bookstore>

我们可以使用 XML::Simple 模块来解析这个XML文档:

use XML::Simple;
use Data::Dumper;

# 读取XML文件
my $xml = XMLin('bookstore.xml');

# 打印解析后的数据结构
print Dumper($xml);

输出结果:

$VAR1 = {
          'book' => [
                      {
                        'category' => 'COOKING',
                        'title' => {
                                     'lang' => 'en',
                                     'content' => 'Everyday Italian'
                                   },
                        'author' => 'Giada De Laurentiis',
                        'year' => '2005',
                        'price' => '30.00'
                      },
                      {
                        'category' => 'CHILDREN',
                        'title' => {
                                     'lang' => 'en',
                                     'content' => 'Harry Potter'
                                   },
                        'author' => 'J K. Rowling',
                        'year' => '2005',
                        'price' => '29.99'
                      }
                    ]
        };

1.2 使用 XML::LibXML 模块

XML::LibXML 是一个功能更强大的模块,适合处理复杂的XML文档。

1.2.1 安装 XML::LibXML

首先,确保你已经安装了 XML::LibXML 模块。如果没有安装,可以使用以下命令进行安装:

cpan XML::LibXML

1.2.2 解析 XML 文档

我们可以使用 XML::LibXML 模块来解析相同的XML文档:

use XML::LibXML;

# 创建解析器对象
my $parser = XML::LibXML->new();

# 解析XML文件
my $doc = $parser->parse_file('bookstore.xml');

# 遍历所有书籍节点
foreach my $book ($doc->findnodes('/bookstore/book')) {
    my $title = $book->findvalue('title');
    my $author = $book->findvalue('author');
    my $year = $book->findvalue('year');
    my $price = $book->findvalue('price');

    print "Title: $title\n";
    print "Author: $author\n";
    print "Year: $year\n";
    print "Price: $price\n\n";
}

输出结果:

Title: Everyday Italian
Author: Giada De Laurentiis
Year: 2005
Price: 30.00

Title: Harry Potter
Author: J K. Rowling
Year: 2005
Price: 29.99

2. XML 生成

2.1 使用 XML::Simple 生成 XML

我们可以使用 XML::Simple 模块来生成简单的XML文档。

2.1.1 生成 XML 文档

以下是一个生成XML文档的示例:

use XML::Simple;

# 创建数据结构
my $data = {
    bookstore => {
        book => [
            {
                category => 'COOKING',
                title => {
                    lang => 'en',
                    content => 'Everyday Italian'
                },
                author => 'Giada De Laurentiis',
                year => '2005',
                price => '30.00'
            },
            {
                category => 'CHILDREN',
                title => {
                    lang => 'en',
                    content => 'Harry Potter'
                },
                author => 'J K. Rowling',
                year => '2005',
                price => '29.99'
            }
        ]
    }
};

# 生成XML文档
my $xml = XMLout($data, RootName => 'bookstore');

# 打印生成的XML
print $xml;

输出结果:

<bookstore>
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
</bookstore>

2.2 使用 XML::LibXML 生成 XML

XML::LibXML 提供了更灵活的方式来生成XML文档。

2.2.1 生成 XML 文档

以下是一个生成XML文档的示例:

use XML::LibXML;

# 创建文档对象
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');

# 创建根节点
my $root = $doc->createElement('bookstore');
$doc->setDocumentElement($root);

# 创建第一个书籍节点
my $book1 = $doc->createElement('book');
$book1->setAttribute('category', 'COOKING');

my $title1 = $doc->createElement('title');
$title1->setAttribute('lang', 'en');
$title1->appendTextNode('Everyday Italian');
$book1->appendChild($title1);

my $author1 = $doc->createElement('author');
$author1->appendTextNode('Giada De Laurentiis');
$book1->appendChild($author1);

my $year1 = $doc->createElement('year');
$year1->appendTextNode('2005');
$book1->appendChild($year1);

my $price1 = $doc->createElement('price');
$price1->appendTextNode('30.00');
$book1->appendChild($price1);

$root->appendChild($book1);

# 创建第二个书籍节点
my $book2 = $doc->createElement('book');
$book2->setAttribute('category', 'CHILDREN');

my $title2 = $doc->createElement('title');
$title2->setAttribute('lang', 'en');
$title2->appendTextNode('Harry Potter');
$book2->appendChild($title2);

my $author2 = $doc->createElement('author');
$author2->appendTextNode('J K. Rowling');
$book2->appendChild($author2);

my $year2 = $doc->createElement('year');
$year2->appendTextNode('2005');
$book2->appendChild($year2);

my $price2 = $doc->createElement('price');
$price2->appendTextNode('29.99');
$book2->appendChild($price2);

$root->appendChild($book2);

# 打印生成的XML
print $doc->toString(1);

输出结果:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
</bookstore>

3. 实践练习

3.1 练习1:解析并修改XML文档

  1. 使用 XML::LibXML 解析 bookstore.xml 文件。
  2. 找到所有价格低于30的书籍,并将价格增加10%。
  3. 将修改后的XML文档保存到 updated_bookstore.xml 文件中。

3.2 练习2:生成XML文档

  1. 创建一个包含多个员工信息的XML文档。
  2. 每个员工节点应包含 name、age、position 和 salary 子节点。
  3. 使用 XML::LibXML 生成并保存该XML文档。

4. 总结

通过本教程,我们学习了如何使用Perl解析和生成XML文档。XML::Simple 适合处理简单的XML文档,而 XML::LibXML 提供了更强大的功能来处理复杂的XML文档。掌握这些技能将帮助你在实际项目中更好地处理XML数据。