【发布时间】:2014-09-02 06:55:51
【问题描述】:
我必须使用 Perl 解析几个 XML 文件并将变量存储在哈希中。如果可能的话,我想过滤某些属性。稍后在我的代码中,我从哈希中提取数据并插入到数据库中。
我一直在使用XML::Parser,但我更愿意解析成哈希而不是处理遇到的每个标签。有什么建议吗?
我想跳过任何具有kind="dir" 属性的路径。我需要路径的作者、日期、消息和文件类型(文件扩展名)。 <path> 标签可以有任意数量,可以是kind“文件”或“目录”。也可以有多个<logentry>标签。
<?xml version="1.0" encoding="UTF-8"?>
<log>
<logentry revision="3989">
<author>cergyl</author>
<date>2013-07-19T05:31:01.212620Z</date>
<paths>
<path action="M" kind="dir">/team.admin/trunk/auth.conf</path>
</paths>
<path action="M" kind="file">/team.admin/trunk/file.cpp</path>
<msg>Whitespace change to verify repository synchronization</msg>
</logentry>
</log>
my $XML_Parser = XML::Parser->new(
Handlers => {
Start => \&hdl_xml_tag_start,
End => \&hdl_xml_tag_end,
Char => \&hdl_xml_nonmarkup_char,
Default => \&hdl_xml_default
}
);
# This event is generated when an XML start tag is recognized. Parser is an XML::Parser::Expat instance.
sub hdl_xml_tag_start
{
my ( $parser, $element, %attributes ) = @_;
$attributes{ '_str' } = "$element:";
$XML_Attributes_Hash_Ref = \%attributes;
return;
}
# This event is generated when an XML end tag is recognized. Note that an XML empty tag (<foo/>) generates both a start and an end event.
sub hdl_xml_tag_end
{
my ( $parser, $element ) = @_;
#format_message($XML_Attributes_Hash_Ref);
format_svn_history( $XML_Attributes_Hash_Ref );
return;
}
# This event is generated when non-markup is recognized. The non-markup sequence of characters is in String.
# A single non-markup sequence of characters may generate multiple calls to this handler.
sub hdl_xml_nonmarkup_char
{
my ( $parser, $string ) = @_;
$XML_Attributes_Hash_Ref->{ '_str' } .= $string;
return;
}
#This is called for any characters that don't have a registered handler.
sub hdl_xml_default { return; }
【问题讨论】:
-
为什么
XML::Parser不适合你? -
我真的很喜欢 XML::Twig,尤其是因为它让我可以
purge来节省内存占用。 -
XML::Parser 是一种低级解析。我同意你摆脱它的愿望。但是,我建议不要使用产生散列的解析器。它们是最难使用的。我使用 XML::LibXML(非常快,非常强大,支持任何 XML),但 XML::Twig 也很流行(尤其是当您的 XML 文件是一长串记录时)。
-
您的 XML 结构相当混乱。单个
logentry不足以了解其他条目的外观。您想完全忽略所有paths元素,只使用msg之前的path?这些path元素中是否总是只有一个?如果没有更多信息,很难为您提供帮助 -
如果您需要帮助,那么您必须更好地解释自己。 “将变量存储在哈希中” 和 “如果可能,过滤某些属性” 根本没有帮助。请展示您希望查看的结果哈希示例,以及“通过某些属性过滤” 的含义。请不要仅仅因为您已经看到或听说过将 XML 处理为哈希的模块而要求哈希。这样做很明显是一个雷区,应该避免。选择最适合您在读取数据后对数据执行的操作的数据表示形式。
标签: perl xml-parsing