如何用awk、Perl或Python解析XML文档?
我有一个XML文件,里面的数据格式是这样的:
<net NetName="abc" attr1="123" attr2="234" attr3="345".../>
<net NetName="cde" attr1="456" attr2="567" attr3="678".../>
....
有没有人能告诉我,怎么用一行命令在awk中提取这个XML文件里的数据?比如,我想知道abc的attr3是什么,它应该会返回给我345。
5 个回答
xmlgawk 可以很简单地处理 XML 文件。
$ xgawk -lxml 'XMLATTR["NetName"]=="abc"{print XMLATTR["attr3"]}' test.xml
这个一行代码可以解析 XML,并输出 "345"。
我写了一个叫做 xml_grep2
的工具,它是基于 XML::LibXML 的,这个是 Perl 语言用来操作 libxml2 的接口。
你可以通过以下方式找到你想要的值:
xml_grep2 -t '//net[@NetName="abc"]/@attr3' to_grep.xml
这个工具可以在 http://xmltwig.com/tool/ 找到。
一般来说,你不应该这样做。解析XML或HTML本身就很复杂,如果再想要把它做得简洁,那就更难了。虽然你可能能拼凑出一个能处理部分XML的解决方案,但最终它还是会出问题。
而且,已经有很多优秀的编程语言和很棒的XML解析工具,为什么不直接用这些工具,让自己的工作变得简单呢?
我不知道awk是否有专门的XML解析器,但如果你想用awk来解析XML,可能会得到很多“锤子是用来钉钉子的,螺丝刀是用来拧螺丝的”这样的回答。我相信是可以做到的,但用Perl写个简单的脚本,利用XML::Simple(这是我个人的最爱)或者其他的XML解析模块,可能会更容易。
为了完整起见,我想说,如果你的代码片段是整个文件的例子,那它并不是有效的XML。有效的XML应该有开始和结束标签,像这样:
<netlist>
<net NetName="abc" attr1="123" attr2="234" attr3="345".../>
<net NetName="cde" attr1="456" attr2="567" attr3="678".../>
....
</netlist>
我相信无效的XML也有它的用处,但一些XML解析器可能会对此发出警告,所以除非你真的想用awk的一行代码来“解析”你的“XML”,否则你可能要考虑让你的XML变得有效。
关于你的修改,我仍然不打算用一行代码来实现,但这里有一个你可以使用的Perl脚本:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
sub usage {
die "Usage: $0 [NetName] ([attr])\n";
}
my $file = XMLin("file.xml", KeyAttr => { net => 'NetName' });
usage() if @ARGV == 0;
exists $file->{net}{$ARGV[0]}
or die "$ARGV[0] does not exist.\n";
if(@ARGV == 2) {
exists $file->{net}{$ARGV[0]}{$ARGV[1]}
or die "NetName $ARGV[0] does not have attribute $ARGV[1].\n";
print "$file->{net}{$ARGV[0]}{$ARGV[1]}.\n";
} elsif(@ARGV == 1) {
print "$ARGV[0]:\n";
print " $_ = $file->{net}{$ARGV[0]}{$_}\n"
for keys %{ $file->{net}{$ARGV[0]} };
} else {
usage();
}
你可以在命令行运行这个脚本,传入1或2个参数。第一个参数是你想查找的'NetName'
,第二个是你想查找的属性。如果没有给出属性,它应该会列出该'NetName'
的所有属性。