2017-04-19 44 views
0

我需要打印带有点的XML标记。 例如:bg.tres,resume.pr 下面是我试过的代码,但它在第一次匹配后停止。我试图首先提取标签,然后确定标签中有点。Perl脚本遍历XML标记并列出所有标记点的标记

my $xml = q~<?xml version='1.0'?> 
<bg.tres> 
<resume.key='267298871' score='5'> 
    <xpath path='xpath://resume'> 
    <resume.pr canonversion='2' dateversion='2' present='734060'> 
    </resume.pr> 
    </xpath> 
</resume> 
</bg.tres>~; 

#print $xml,$/; 
foreach $line($xml) 
{ 
    if($line =~ m/<(.*?)>/) 
    { 
     print "$1\n"; 
    } 
} 

谁能请审查,因为所有的例子都存在与封装和模块的使用,但我需要用简单的逻辑执行它,而功能。没有这样的例子,请建议。

+1

使用XML解析器 –

+0

两个问题:1)这不是XML。 b)如果它是XML,用正则表达式解析它并不重要,因为XML是上下文的,正则表达式不是。 c)有些模块是XML解析器。你应该使用一个。 – Sobrique

+0

这看起来不像格式良好的XML?您是否考虑过使用格式良好的XML和XML解析器? – Doqnach

回答

-1

在@xml中,你只有一行,所以你的正则表达式不能工作。

你需要拆分你的字符串。

重命名@xml在$ XML,然后

my @xml = split(/\n/,$xml); 

if ($line =~ m/<([^>]+(?=\.)[^>]+)>/) 

此代码的工作对我来说:

my $xml = q~<?xml version='1.0'?> 
<bg.tres> 
<resume.key='267298871' score='5'> 
    <xpath path='xpath://resume'> 
    <resume.pr canonversion='2' dateversion='2' present='734060'> 
    </resume.pr> 
    </xpath> 
</resume> 
</bg.tres>~; 


#print $xml,$/; 
my @xml = split(/\n/,$xml); 

foreach $line(@xml) 
{ 
    if($line =~ m/<([^>]+(?=\.)[^>]+)>/) 
    { 
     print "$1\n"; 
    } 
} 
+0

现在它的工作,但正则表达式如果($行=〜m/<(.*?)> /)比if($ line =〜m/<([^>)+(?= \)更准确地工作。)[^>] +)> /),因为标记xpath从输出中丢失。谢谢:) –

+0

有趣!用你的正则表达式,我得到了:?xml version ='1.0'? bg.tres resume.key ='267298871'score ='5' xpath path ='xpath:// resume' resume.pr canonversion ='2'dateversion ='2'present ='734060' /resume .pr /xpath /resume /bg.tres 它与您的请求“具有点的XML标记”不匹配。 – Plaute

2

有一对夫妇与您的要求的问题:

  1. 这不是XML。如果这真的是你的源XML,我建议你去打一个XML规范的卷发副本给你。因为畸形的XML是应该是致命的

  2. XML是上下文的。正则表达式不是。因此用正则表达式解析XML非常复杂(这不是相当于不可能,但很难)。

  3. xpath是正则表达式的XML等价物。有点。它是上下文的,允许您根据XML结构进行选择和匹配,区分内容,标签和属性。

  4. 解析器使工作变得简单。使用解析器。

  5. 您正在将文本插入数组@xml,但它是单个值。所以不要使用标量。 foreach @xml没有做你认为正在做的事情,因为@xml中只有一个元素。

所以考虑到这一点 - 和修复您的XML少是需要使它有效的XML:

#!/usr/bin/env perl; 
use strict; 
use warnings; 

use XML::Twig; 

my $src = q~<?xml version='1.0'?> 
<bg.tres> 
<resume.key key='267298871' score='5'> 
    <xpath path='xpath://resume'> 
    <resume.pr canonversion='2' dateversion='2' present='734060'> 
    </resume.pr> 
    </xpath> 
</resume.key> 
</bg.tres>~; 

my $xml = XML::Twig -> parse ($src); 

foreach my $node ($xml -> get_xpath ('//*')) { 
    print $node -> tag,"\n" if $node -> tag =~ m/\./; 
} 
+0

实际需求是这样的,我有一个XML文件,并且必须列出所有具有(。)圆点的标签,而不使用构建函数中的分析器或任何XML。所以我试着通过正则表达式来做。但正如你所提到的那样,它的难以置信的复杂性,你能否提出任何简单的逻辑,如使用字符串函数或其他任何东西,而不是解析器。 –

+0

不。没有'简单的逻辑',因为XML不是那么简单。对于需要解析器的事物不使用解析器,意味着您需要自己编写解析器。所以......也许去看看XML :: Twig的源代码吧? (提示:它也非常复杂) – Sobrique

+1

您是说需要在没有XML解析器的情况下处理XML?这有点像没有扳手拧紧螺母的要求。要求用错误的工具做某件事是你应该离开的要求。 –