您使用哪個工具來分析split(或grep)的結果? xmllint
(來自libxml2
)抱怨,但xmlwf
(從expat
)沒有。所以我認爲任何基於expat的工具都適用於XML,但不是基於libxml2的工具。
看起來像xml_split
和xml_grep
雖然可以聲明命名空間。至少它應該是一個選擇。我會看看它。
在此期間,這裏是進行後處理您xml_grep
得到結果的quick'n骯髒的方式:
xml_grep --root 'SubInformation' --cond 'SubInformationName[string()="Blah"]' Infile.xml | perl -MXML::Twig -e'XML::Twig->new(start_tag_handlers => { xml_grep => sub { $_->set_att("xmlns:m" => "http://m.org") }, SubInformation => sub { $_->flush } })->parse(\*STDIN)' > Outfile.xml
更換xmlns:m
和"http://m.org"
用適當的值。
讓我想想一個以通用方式完成此操作的方法,其結果爲xml_split
。我可以假定名稱空間聲明不是太棘手(即前綴(es)只聲明一次)?
編輯:這裏是添加命名空間聲明從xml_split
產生的文件,把它作爲add_ns Infile
您已經在Infile.xml運行xml_split
後一種方式:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $root= shift @ARGV;
my($base, @files)= sort glob("$root-*.xml");
my %ns= ns_for_file($base);
foreach my $file (@files)
{ add_ns($file, %ns); }
sub ns_for_file
{ my($base)= @_;
my %ns;
XML::Twig->new(start_tag_handlers
# get namespace declarations from the root and bail
=> { 'level(0)' => sub { %ns= ns_for_tag($_);
$_[0]->finish_now();
}
},
)
->parsefile($base);
return %ns;
}
# get all namespace declarations from the root element
sub ns_for_tag
{ my($e)= @_;
return map { $_ => $e->att($_) if m{^xmlns:} } $e->att_names;
}
sub add_ns
{ my($file, %ns)= @_;
XML::Twig->new(start_tag_handlers => { 'level(0)' => sub { $_->set_att(%ns); } },
twig_handlers => { _all_ => sub { $_->flush; } },
keep_spaces => 1,
)
->parsefile_inplace($file);
}
我使用libxml2 ...或者實際上是「R」(統計語言)中的libxml2的包裝。如果拆分文件可以被libxml2解析,那將非常好。並感謝這個偉大的工具! – Chris
謝謝,現在測試。當我在原始文件上運行grep xmlns時,我看到5個不同的xmlns:xx =「abc123」,是不是你所說的前綴只聲明過一次? 5箇中的每一個都只列出了onec。 – Chris
是否都是根元素上的命名空間聲明? – mirod