如何使用awk,Perl或Python挖掘XML文档?

时间:2009-05-26 05:35:58

标签: python xml perl awk

我有一个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 个答案:

答案 0 :(得分:7)

一般来说,you don't。 XML / HTML解析很难,而不是简洁地完成它,虽然你可能能够将一个有限的XML子集成功地解决成功的解决方案,但最终它会破坏。

此外,there are many great languages with great XML parsers already written,为什么不使用其中一个让你的生活更轻松?

我不知道是否为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 one-liner尝试半解析“解析”你的“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'的所有属性。

答案 1 :(得分:7)

我编写了一个名为xml_grep2的工具,基于XML::LibXMLlibxml2的perl接口。

您可以通过以下方式找到您正在寻找的价值:

xml_grep2 -t '//net[@NetName="abc"]/@attr3' to_grep.xml

该工具可在http://xmltwig.com/tool/

找到

答案 2 :(得分:5)

xmlgawk可以非常轻松地使用XML。

$ xgawk -lxml 'XMLATTR["NetName"]=="abc"{print XMLATTR["attr3"]}' test.xml

这个衬里可以解析XML并打印“345”。

答案 3 :(得分:2)

如果您没有xmlgawk并且您的XML格式已修复,那么正常的awk就可以。

$ nawk -F '[ ="]+' '/abc/{for(i=1;i<=NF;i++){if($i=="attr3"){print $(i+1)}}}' test.xml

此脚本可以返回“345”。 但我认为这非常危险,因为普通的awk无法使用XML。

答案 4 :(得分:0)

您可以尝试这个漂亮的小脚本:http://awk.info/?doc/tools/xmlparse.html