我有xml,其中我有标签<test>Value</test>
。我想得到标签的值。我想用Perl正则表达式来做
下面是我的xml示例:
<?xml version="1.0"?>
<t_volume>
<test>Value</test>
<info>
<info_name>FZGA34177.b1</info_name>
<center_project>4085729</center_project>
<base_file>SETARIA_ITALICA/JGI/fasta/FZGA34177.b1.fasta</base_file>
</info>
</t_volume>
我想获得此标记<test>Value</test>
的值。我尝试过,但我无法获得该值。
$data = ($xml =~/<test>(.*?)<\/test>/i);
在xml中我得到的xml也像
<Test RequestId="1" RequestorId="test" ResponderId="Test">
我怎样才能获得RequestorId
答案 0 :(得分:2)
不要使用正则表达式来解析XML。使用适当的XML处理工具,即XML::LibXML:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use XML::LibXML;
my $dom = 'XML::LibXML'->load_xml( location => shift );
my $data = $dom->findvalue('t_volume/test');
say $data;
my $requestor_id = $dom->findvalue('//Test/@RequestorId');
say $requestor_id;
答案 1 :(得分:2)
正则表达式是用于XML的bad idea,因为正则表达式不是上下文,而XML就是上下文。问题是 - 有一堆语义上相同的XML
部分可以合法地变化并且会绊倒regex
。您可以通过这样做来创建脆弱的代码,因为它可能因为上游(合法的,规范内)更改而有一天会中断。
E.g:
<root>
<Test RequestId="1" RequestorId="test" ResponderId="Test">
</Test>
</root>
或者:
<root>
<Test RequestId="1" RequestorId="test" ResponderId="Test"></Test>
</root>
或者:
<root>
<Test
RequestId="1"
RequestorId="test"
ResponderId="Test"></Test>
</root>
或者:
<root
><Test
RequestId="1"
RequestorId="test"
ResponderId="Test"
></Test></root>
或者:
<root>
<Test RequestId="1" RequestorId="test" ResponderId="Test"/>
</root>
这些都在语义上是相同的,但我很确定你会被regex
用来安全地处理上述所有内容(以及你可能遇到的任何其他内容)< / p>
另外:
Test
元素)<Test>
元素,因为您是通配符,它会捕获那些元素,而不是属性。 幸运的是,您有另一种选择 - xpath
- 一种定义表达式的方法,有点像regex
,但是以XML
方式识别。
我建议XML::Twig
,因为它没有特别陡峭的学习曲线。第一次:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> new -> parsefile ( 'your_file.xml' );
print $twig -> get_xpath('//test',0) -> text;
对于你的第二个:
print $twig -> get_xpath('//Test',0) -> att('RequestorId');
这可以是单行 - 如果:
perl -MXML::Twig -0777 -e 'print XML::Twig -> parse ( <> ) -> get_xpath("//test",0) -> text' yourfile
答案 2 :(得分:1)
$xml =~/<test>(.*?)<\/test>/i
表达式可以在列表上下文中计算,在这种情况下,它返回一个包含所有捕获组的数组。所以你需要做那样的事情:
($data) = $xml =~/<test>(.*?)<\/test>/i;
编辑:对于第二个示例,如果使用一组括号捕获信息,则可以类似地提取信息:
($RequestorId) = $xml =~ /<Test [^>]*\bRequestorId="([^"]*)"/;